Skip to content

Commit 21c027d

Browse files
committed
+ contains and isSubset to HashSet
1 parent f614035 commit 21c027d

File tree

2 files changed

+19
-73
lines changed

2 files changed

+19
-73
lines changed

docsrc/content/computation-expressions.fsx

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,5 @@
1-
(*** hide ***)
2-
// This block of code is omitted in the generated HTML documentation. Use
3-
// it to define helpers that you do not want to show in the documentation.
41

5-
#r @"../../src/FSharpPlus/bin/Release/net8.0/FSharpPlus.dll"
6-
open FSharpPlus
7-
open FSharpPlus.Data
8-
9-
(**
10-
Computations Expressions
11-
========================
12-
13-
This library allows to use some common computation expressions without writing any boiler plate code.
14-
15-
For [Applicatives](abstraction-applicative.html) there is single computation expression: ``applicative { .. }``. Additionally ``applicative2 { .. }`` and ``applicative3 { .. }`` exists for composed (aka layered) applicatives.
16-
17-
For [ZipApplicatives](abstraction-zipapplicative.html) there is a counterpart set of computation expressions: ``applicative' { .. }``, ``applicative2' { .. }`` and ``applicative3' { .. }``.
18-
19-
For [monadic](abstraction-monad.html) code there is a single computation expression: ``monad { .. }`` but it comes in 4 flavours:
20-
21-
- Delayed or strict
22-
23-
Delayed computations require that the type implements a TryWith, TryFinally and optionally a Delay method.
24-
F# comes with async and seq computation expressions, both are delayed.
25-
26-
- It can have embedded side-effects or act as a monadplus
27-
28-
A monadplus can return (or yield) many times, so for example all expressions in a loop can be returned, whereas in the other model those expressions are of type unit, since a side effect is expected.
29-
30-
Async workflows is an example of a side-effect computation expression and seq expressions are an example of monadplus.
31-
32-
Side effect workflows don't have any additional requirement over the type (apart from the monad operations), but monadplus requires the additional [get_Empty and (<|>)](abstraction-alternative.html) methods.
33-
34-
The generic computation expression ``monad`` is a side-effect one, but it can be turned into a monadplus by accessing the ``.plus`` property.
35-
Note that ``monad.fx`` is an alias for ``monad``: fx is used as an abbreviation for side-effects.
36-
37-
These computations are lazy by default, but they can be made strict by adding ``.strict`` or using a ``'``, ie ``monad.plus'``.
38-
39-
In other words:
40-
41-
- ``monad.fx`` or simply ``monad``: Lazy monadic builder. Use when you want to use side-effects instead of the additive behavior of monad plus.
42-
- ``monad.fx.strict`` (or ``monad.fx'`` or simply ``monad.strict`` or ``monad'``) is the strict version of ``monad``.
43-
- ``monad.plus``: Lazy additive monadic builder. Use when you expect one or more results.
44-
- ``monad.plus'`` is the strict version of ``monad.plus``
45-
46-
Note that a type is either lazy or strict, but it could act as fx or plus at the same time (see below some examples). This means that we need to pay attention when using a CE over a type, if the type is lazy but with use a strict monad, we'll get strict semantics which probably would make no sense, but if we do the opposite we might run into runtime errors, fortunately a compile-time warning (or error) will prevent us.
47-
48-
A simple way to find out if a type is strict or lazy is to execute this in fsi: `let _ : MyType<'t> = monad { printfn "I'm strict" }`
49-
50-
For layered monads (monad transformers) the general rule is: the monad is strict unless at least one of its constituent types is lazy, in that case the whole monad becomes lazy.
51-
52-
*)
53-
54-
let _ : OptionT<list<unit option>> = monad { printfn "I'm strict" }
55-
// will print I'm strict, because OptionT and list are strict
56-
57-
let _ : OptionT<seq<unit option>> = monad { printfn "I'm strict" }
58-
// won't print anything, because seq is lazy
59-
60-
(**
61-
62-
63-
Examples
64-
========
65-
66-
You may run this script step-by-step.
67-
68-
69-
*)
70-
71-
(**
72-
```f#
732
#r @"nuget: FSharpPlus"
74-
```
75-
*)
763
open FSharpPlus
774

785
let lazyValue = monad {

src/FSharpPlus/Extensions/HashSet.fs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,22 @@ module HashSet =
5555
for item in source do
5656
result.Add (mapping item) |> ignore
5757
result
58+
59+
/// <summary>Determines whether a HashSet contains a specific value.</summary>
60+
/// <param name="value">The value to look for in the set.</param>
61+
/// <param name="source">The set to look in.</param>
62+
/// <returns><c>true</c> if the set contains <c>value</c>; otherwise, <c>false</c>.</returns>
63+
[<CompiledName("Contains")>]
64+
let contains (value: 'T) (source: HashSet<'T>) : bool =
65+
raiseIfNull (nameof source) source
66+
source.Contains value
67+
68+
/// <summary>Determines whether the first set is a subset of the second set.</summary>
69+
/// <param name="source1">The first input set.</param>
70+
/// <param name="source2">The second input set.</param>
71+
/// <returns><c>true</c> if <c>source1</c> is a subset of <c>source2</c>; otherwise, <c>false</c>.</returns>
72+
[<CompiledName("IsSubset")>]
73+
let isSubset (source1: HashSet<'T>) (source2: HashSet<'T>) : bool =
74+
raiseIfNull (nameof source1) source1
75+
raiseIfNull (nameof source2) source2
76+
source1.IsSubsetOf source2

0 commit comments

Comments
 (0)