Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 107 additions & 33 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,135 @@

## Solution Structure

**IMPORTANT: Every collection binding implementation file must have a corresponding `.fsi` signature file.**
**IMPORTANT: Every collection binding implementation file must have a corresponding `.fsi` signature file.** The one
exception is the `XTypes.fs` file of a folder, which holds only type abbreviations and is its own signature: a signature
file without an implementation file does not compile (FS0240).

The comparer struct and the extension files of a module carry `<DependentUpon>` in the project file, the `.fsi` on the
module's `.fsi` and the `.fs` on its `.fs`, so that Visual Studio shows them as a tree under the module.

```text
/
β”œβ”€β”€ build/ – FAKE build scripts and release automation
β”‚ └── CheckOrder.fs – checks the category order of the signature files with the Fantomas parser
β”œβ”€β”€ docsSrc/ – FSharp.Formatting documentation source
β”œβ”€β”€ src/FSharp.Collections.Immutable/ – main library
β”‚ β”œβ”€β”€ Helper.fs
β”‚ β”œβ”€β”€ ComputationExpressions.fs
β”‚ β”œβ”€β”€ Helper.fs – argument checks and exceptions shared by the modules
β”‚ β”œβ”€β”€ FlatList/ – ImmutableArray API surface and builders
β”‚ β”‚ β”œβ”€β”€ FlatList.fs / FlatList.fsi
β”‚ β”‚ β”œβ”€β”€ FlatListBuilder.fs
β”‚ β”‚ └── FlatListCE.fs
β”‚ β”‚ β”œβ”€β”€ FlatListTypes.fs – the FlatList abbreviation
β”‚ β”‚ β”œβ”€β”€ FlatList.fs / FlatList.fsi – includes the nested Parallel module
β”‚ β”‚ β”œβ”€β”€ FlatListOption.fs / FlatListOption.fsi – Option namespace overrides
β”‚ β”‚ β”œβ”€β”€ FlatListTuple.fs / FlatListTuple.fsi – Tuple namespace overrides
β”‚ β”‚ β”œβ”€β”€ FlatListBuilder.fs / FlatListBuilder.fsi
β”‚ β”‚ └── FlatListCE.fs / FlatListCE.fsi
β”‚ β”œβ”€β”€ IndexedList/ – ImmutableList API surface and builders
β”‚ β”‚ β”œβ”€β”€ IIndexedList.fs / IIndexedList.fsi
β”‚ β”‚ β”œβ”€β”€ IndexedListTypes.fs
β”‚ β”‚ β”œβ”€β”€ IndexedList.fs / IndexedList.fsi
β”‚ β”‚ β”œβ”€β”€ IndexedListBuilder.fs
β”‚ β”‚ └── IndexedListCE.fs
β”‚ β”‚ β”œβ”€β”€ IndexedListOption.fs / IndexedListOption.fsi
β”‚ β”‚ β”œβ”€β”€ IndexedListTuple.fs / IndexedListTuple.fsi
β”‚ β”‚ β”œβ”€β”€ IIndexedList.fs / IIndexedList.fsi
β”‚ β”‚ β”œβ”€β”€ IIndexedListOption.fs / IIndexedListOption.fsi
β”‚ β”‚ β”œβ”€β”€ IIndexedListTuple.fs / IIndexedListTuple.fsi
β”‚ β”‚ β”œβ”€β”€ IndexedListBuilder.fs / IndexedListBuilder.fsi
β”‚ β”‚ └── IndexedListCE.fs / IndexedListCE.fsi
β”‚ β”œβ”€β”€ Queue/ – ImmutableQueue API surface and CE
β”‚ β”‚ β”œβ”€β”€ IQueue.fs / IQueue.fsi
β”‚ β”‚ β”œβ”€β”€ QueueTypes.fs – the Queue and IQueue abbreviations
β”‚ β”‚ β”œβ”€β”€ Queue.fs / Queue.fsi
β”‚ β”‚ └── QueueCE.fs
β”‚ β”‚ β”œβ”€β”€ QueueOption.fs / QueueOption.fsi
β”‚ β”‚ β”œβ”€β”€ QueueTuple.fs / QueueTuple.fsi
β”‚ β”‚ β”œβ”€β”€ IQueue.fs / IQueue.fsi
β”‚ β”‚ β”œβ”€β”€ IQueueOption.fs / IQueueOption.fsi
β”‚ β”‚ β”œβ”€β”€ IQueueTuple.fs / IQueueTuple.fsi
β”‚ β”‚ └── QueueCE.fs / QueueCE.fsi
β”‚ β”œβ”€β”€ Stack/ – ImmutableStack API surface and CE
β”‚ β”‚ β”œβ”€β”€ IStack.fs / IStack.fsi
β”‚ β”‚ β”œβ”€β”€ StackTypes.fs – the Stack and IStack abbreviations
β”‚ β”‚ β”œβ”€β”€ Stack.fs / Stack.fsi
β”‚ β”‚ └── StackCE.fs
β”‚ β”‚ β”œβ”€β”€ StackOption.fs / StackOption.fsi
β”‚ β”‚ β”œβ”€β”€ StackTuple.fs / StackTuple.fsi
β”‚ β”‚ β”œβ”€β”€ IStack.fs / IStack.fsi
β”‚ β”‚ β”œβ”€β”€ IStackOption.fs / IStackOption.fsi
β”‚ β”‚ β”œβ”€β”€ IStackTuple.fs / IStackTuple.fsi
β”‚ β”‚ └── StackCE.fs / StackCE.fsi
β”‚ β”œβ”€β”€ HashMap/ – ImmutableDictionary API surface and CE
β”‚ β”‚ β”œβ”€β”€ IHashMap.fs / IHashMap.fsi
β”‚ β”‚ β”œβ”€β”€ HashMap.fs / HashMap.fsi
β”‚ β”‚ └── HashMapCE.fs
β”‚ β”‚ β”œβ”€β”€ HashMapTypes.fs – the HashMap and IMap abbreviations
β”‚ β”‚ β”œβ”€β”€ HashMap.fs / HashMap.fsi – nested Tuple / ValueTuple submodules
β”‚ β”‚ β”‚ β”œβ”€β”€ HashMap.CustomComparers.fs / .fsi – creates hash maps with comparers
β”‚ β”‚ β”‚ └── HashMap.Extensions.fs / .fsi – ofArray / ofList / ofSeq for every binding shape
β”‚ β”‚ β”œβ”€β”€ HashMapOption.fs / HashMapOption.fsi
β”‚ β”‚ β”œβ”€β”€ HashMapTuple.fs / HashMapTuple.fsi
β”‚ β”‚ β”œβ”€β”€ IMap.fs / IMap.fsi
β”‚ β”‚ β”œβ”€β”€ IMapOption.fs / IMapOption.fsi
β”‚ β”‚ β”œβ”€β”€ IMapTuple.fs / IMapTuple.fsi
β”‚ β”‚ └── HashMapCE.fs / HashMapCE.fsi
β”‚ β”œβ”€β”€ SortedMap/ – ImmutableSortedDictionary API surface and CE
β”‚ β”‚ β”œβ”€β”€ ISortedMap.fs / ISortedMap.fsi
β”‚ β”‚ β”œβ”€β”€ SortedMapTypes.fs
β”‚ β”‚ β”œβ”€β”€ SortedMap.fs / SortedMap.fsi
β”‚ β”‚ └── SortedMapCE.fs
β”‚ β”‚ β”‚ β”œβ”€β”€ SortedMap.CustomComparers.fs / .fsi
β”‚ β”‚ β”‚ └── SortedMap.Extensions.fs / .fsi
β”‚ β”‚ β”œβ”€β”€ SortedMapOption.fs / SortedMapOption.fsi
β”‚ β”‚ β”œβ”€β”€ SortedMapTuple.fs / SortedMapTuple.fsi
β”‚ β”‚ └── SortedMapCE.fs / SortedMapCE.fsi
β”‚ β”œβ”€β”€ HashSet/ – ImmutableHashSet API surface and CE
β”‚ β”‚ β”œβ”€β”€ IHashSet.fs / IHashSet.fsi
β”‚ β”‚ β”œβ”€β”€ HashSetTypes.fs
β”‚ β”‚ β”œβ”€β”€ HashSet.fs / HashSet.fsi
β”‚ β”‚ └── HashSetCE.fs
β”‚ └── SortedSet/ – ImmutableSortedSet API surface and CE
β”‚ β”œβ”€β”€ ISortedSet.fs / ISortedSet.fsi
β”‚ β”œβ”€β”€ SortedSet.fs / SortedSet.fsi
β”‚ └── SortedSetCE.fs
β”‚ β”‚ β”‚ └── HashSet.CustomComparer.fs / .fsi – creates hash sets with a comparer
β”‚ β”‚ β”œβ”€β”€ HashSetOption.fs / HashSetOption.fsi
β”‚ β”‚ β”œβ”€β”€ HashSetTuple.fs / HashSetTuple.fsi
β”‚ β”‚ β”œβ”€β”€ ISet.fs / ISet.fsi
β”‚ β”‚ β”œβ”€β”€ ISetOption.fs / ISetOption.fsi
β”‚ β”‚ β”œβ”€β”€ ISetTuple.fs / ISetTuple.fsi
β”‚ β”‚ └── HashSetCE.fs / HashSetCE.fsi
β”‚ β”œβ”€β”€ SortedSet/ – ImmutableSortedSet API surface and CE
β”‚ β”‚ β”œβ”€β”€ SortedSetTypes.fs
β”‚ β”‚ β”œβ”€β”€ SortedSet.fs / SortedSet.fsi
β”‚ β”‚ β”‚ └── SortedSet.CustomComparer.fs / .fsi
β”‚ β”‚ β”œβ”€β”€ SortedSetOption.fs / SortedSetOption.fsi
β”‚ β”‚ β”œβ”€β”€ SortedSetTuple.fs / SortedSetTuple.fsi
β”‚ β”‚ └── SortedSetCE.fs / SortedSetCE.fsi
β”‚ β”œβ”€β”€ FrozenMap/ – FrozenDictionary API surface and CE
β”‚ β”‚ β”œβ”€β”€ FrozenMapTypes.fs
β”‚ β”‚ β”œβ”€β”€ FrozenMap.fs / FrozenMap.fsi
β”‚ β”‚ β”‚ β”œβ”€β”€ FrozenMap.CustomComparers.fs / .fsi
β”‚ β”‚ β”‚ └── FrozenMap.Extensions.fs / .fsi
β”‚ β”‚ β”œβ”€β”€ FrozenMapOption.fs / FrozenMapOption.fsi
β”‚ β”‚ β”œβ”€β”€ FrozenMapTuple.fs / FrozenMapTuple.fsi
β”‚ β”‚ └── FrozenMapCE.fs / FrozenMapCE.fsi
β”‚ β”œβ”€β”€ FrozenSet/ – FrozenSet API surface and CE (the BCL type keeps its name)
β”‚ β”‚ β”œβ”€β”€ FrozenSet.fs / FrozenSet.fsi
β”‚ β”‚ β”‚ └── FrozenSet.CustomComparer.fs / .fsi
β”‚ β”‚ β”œβ”€β”€ FrozenSetOption.fs / FrozenSetOption.fsi
β”‚ β”‚ β”œβ”€β”€ FrozenSetTuple.fs / FrozenSetTuple.fsi
β”‚ β”‚ └── FrozenSetCE.fs / FrozenSetCE.fsi
β”‚ └── ComputationExpressions.fs / .fsi – the computation expression instances
└── tests/FSharp.Collections.Immutable.Tests/ – MSTest test project
β”œβ”€β”€ HelperTests.fs
β”œβ”€β”€ TestCategories.fs – centralized custom test category attributes
β”œβ”€β”€ FlatList/ – focused test files per operation group
β”œβ”€β”€ IndexedList/ – focused test files per operation group
β”œβ”€β”€ HashMap/ – focused test files per operation group
β”œβ”€β”€ SortedMap/ – focused test files per operation group
β”œβ”€β”€ HashSet/ – focused test files per operation group
β”œβ”€β”€ SortedSet/ – focused test files per operation group
β”œβ”€β”€ Queue/ – focused test files per operation group
└── Stack/ – focused test files per operation group
β”œβ”€β”€ TestCategoriesTests.fs – enforces the test category rules
β”œβ”€β”€ Contracts/ – shared contract bases, inputs and assertion helpers
└── <Collection>/ – ops records, contract classes, collection-specific,
builder, computation expression, Option and Tuple tests
```

The modules follow ADR 0001 – Per-collection modules (`docsSrc/Explanations/ADR_0001_Collection_Modules.md`):

* Each module groups its functions under banner comments `// ---- Category ----` in the order `Creation`, `Builder`,
`Properties`, `Access`, `Search`, `Transformation`, `Folding`, `Partitioning and grouping`, `Sorting`, `Random`,
`Conversion`, `Type-specific`, and sorts the functions of a category alphabetically (ordinal), active patterns last.
The `.fs` file repeats the order of its `.fsi` file. `build/CheckOrder.fs` (FAKE target `CheckOrder`) enforces it.
* A file with one module declares it as the root module of the file (`module FSharp.Collections.Immutable.FlatList`);
the type abbreviations of a folder live in its `XTypes.fs`. No module carries `[<CompiledName>]`.
* `try*` functions return `voption`, tuples are struct tuples. The namespaces `FSharp.Collections.Immutable.Option` and
`FSharp.Collections.Immutable.Tuple` repeat these functions with `option` results and reference tuples.
* No module function creates a collection with comparers: the `CustomComparers*` (maps) and `CustomComparer*` (sets)
structs do, and the modules create the structs with `forComparers`, `forKeyComparer` and `forComparer`.
* Maps take bindings in every shape: `ofArray`, `ofList` and `ofSeq` are static extension members of `XExtensions`,
overloaded for `KeyValuePair`, reference tuples and struct tuples; `addRange` and `setItems` take `KeyValuePair`s, and
the nested `Tuple` and `ValueTuple` submodules of the module take the tuple shapes.
* A function throws what the FSharp.Core function of the mirrored module throws for the same input: `Array` for
`FlatList`, `List` for the other sequence-like modules, `Map` and `Set` for maps and sets.
* Contract test bases in `Contracts/` take a record of the module's functions; a collection derives one test class per
capability that it supports. Expected values and exceptions come from FSharp.Core. The categories are attributes on
the test classes; test methods carry none.

## Libraries in Use

* [`System.Collections.Immutable`](https://www.nuget.org/packages/System.Collections.Immutable/) – immutable collections foundation
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Changed

* The package targets `net8.0` and `net10.0`.
* The package requires FSharp.Core 10.1.301 or later, the first release with `partitionWith`.

## [1.0.0] - 2020-02-23

First release
Expand Down
3 changes: 2 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</ItemGroup>
<ItemGroup Label="FSharp">
<PackageVersion Include="FSharp.Control.Reactive" Version="6.1.2" />
<PackageVersion Include="FSharp.Core" Version="10.0.100" />
<PackageVersion Include="FSharp.Core" Version="10.1.301" />
</ItemGroup>
<ItemGroup Label="Build and Test">
<PackageVersion Include="Argu" Version="6.2.5" />
Expand All @@ -24,6 +24,7 @@
<PackageVersion Include="Fake.DotNet.Paket" Version="6.2.0" />
<PackageVersion Include="Fake.IO.FileSystem" Version="6.2.0" />
<PackageVersion Include="Fake.Tools.Git" Version="6.2.0" />
<PackageVersion Include="Fantomas.FCS" Version="8.0.10" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.11.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.402" />
<PackageVersion Include="MSTest" Version="4.2.3" />
Expand Down
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ Please also join the [F# Open Source Group](http://fsharp.github.com)

## Features

* `FlatList` (`ImmutableArray`)
* `ImmutableList`
* `Stack` (`ImmutableStack`)
* `Queue` (`ImmutableQueue`)
* `HashMap` (`ImmutableDictionary`)
* `SortedMap` (`ImmutableSortedDictionary`)
* `HashSet` (`ImmutableHashSet`)
* `SortedSet` (`ImmutableSortedSet`)
* `IIndexedSeq` (`IReadOnlyList`)
| Module | .NET type | Computation expression |
|---|---|---|
| `FlatList` | `ImmutableArray<'T>` | – |
| `ImmutableList` | `ImmutableList<'T>` | – |
Comment thread
xperiandri marked this conversation as resolved.
| `Stack` | `ImmutableStack<'T>` | – |
| `Queue` | `ImmutableQueue<'T>` | – |
| `HashMap` | `ImmutableDictionary<'Key, 'Value>` | – |
| `SortedMap` | `ImmutableSortedDictionary<'Key, 'Value>` | – |
| `HashSet` | `ImmutableHashSet<'T>` | – |
| `SortedSet` | `ImmutableSortedSet<'T>` | – |
| `IIndexedSeq` | `IReadOnlyList<'T>` | – |

[Documentation](https://fsprojects.github.io/FSharp.Collections.Immutable/)

Expand Down Expand Up @@ -85,6 +87,7 @@ or
- `GitHubRelease` - Publishes a [GitHub Release](https://help.github.com/en/articles/creating-releases) with the Release Notes and any NuGet packages. Runs only from `Github Actions`.
- `FormatCode` - Runs [Fantomas](https://github.com/fsprojects/fantomas) on the solution file.
- `CheckFormatCode` - Runs [Fantomas --check](https://fsprojects.github.io/fantomas/docs/end-users/FormattingCheck.html) on the solution file.
- `CheckOrder` - Checks, with the parser of [Fantomas](https://github.com/fsprojects/fantomas), that every signature file groups its functions by category in the order of ADR 0001 and sorts them alphabetically inside a category, and that the implementation file repeats the order. Runs before `DotnetBuild`.
- `BuildDocs` - Generates [Documentation](https://fsprojects.github.io/FSharp.Formatting) from `docsSrc` and the [XML Documentation Comments](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/xmldoc/) from your libraries in `src`.
- `WatchDocs` - Generates documentation and starts a webserver locally. It will rebuild and hot reload if it detects any changes made to `docsSrc` files, or libraries in `src`.

Expand Down
Loading
Loading