Skip to content

Commit c62ef67

Browse files
committed
Merge remote-tracking branch 'origin/master' into gus/date-and-time
2 parents 8edea02 + 68b0dc1 commit c62ef67

File tree

19 files changed

+737
-268
lines changed

19 files changed

+737
-268
lines changed

docsrc/content/abstraction-bifunctor.fsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,6 @@ open FSharpPlus
9797
let rInt10Str10 = bimap int string (10.0, 10)
9898

9999

100-
let resOk11 = bimap ((+) 1) string (Ok 10)
100+
let resOk11 = bimap string ((+) 1) (Ok 10)
101101
let rStrTrue = first string (true, 10)
102102
let rStr10 = second string (true, 10)

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 {

docsrc/content/type-matrix.fsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,7 @@ let matrix3x4_3 = matrix3x4_1 + result 5
7171

7272
open FSharpPlus.Math.Generic
7373

74-
let vector3d_4 = matrix3x4_1 + 5G
74+
let vector3d_4 = matrix3x4_1 + 5G
75+
76+
77+
// More docs for type-level stuff here: https://gist.github.com/cannorin/75328a2abdef2c3a397cc71058ce4864

src/FSharpPlus/Control/Applicative.fs

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -42,40 +42,15 @@ type Apply =
4242
let f, x = f.Value, x.Value
4343
KeyValuePair2 (Plus.Invoke a b, f x)
4444

45-
static member ``<*>`` (struct (f: Map<'Key,_> , x: Map<'Key,'T> ) , _output: Map<'Key,'U> , [<Optional>]_mthd: Apply) : Map<'Key,'U> = Map (seq {
46-
for KeyValue(k, vf) in f do
47-
match Map.tryFind k x with
48-
| Some vx -> yield k, vf vx
49-
| _ -> () })
50-
51-
static member ``<*>`` (struct (f: Dictionary<'Key,_>, x: Dictionary<'Key,'T>) , _output: Dictionary<'Key,'U> , [<Optional>]_mthd: Apply) : Dictionary<'Key,'U> =
52-
let dct = Dictionary ()
53-
for KeyValue(k, vf) in f do
54-
match x.TryGetValue k with
55-
| true, vx -> dct.Add (k, vf vx)
56-
| _ -> ()
57-
dct
58-
59-
static member ``<*>`` (struct (f: IDictionary<'Key,_>, x: IDictionary<'Key,'T>) , _output: IDictionary<'Key,'U> , [<Optional>]_mthd: Apply) : IDictionary<'Key,'U> =
60-
let dct = Dictionary ()
61-
for KeyValue(k, vf) in f do
62-
match x.TryGetValue k with
63-
| true, vx -> dct.Add (k, vf vx)
64-
| _ -> ()
65-
dct :> IDictionary<'Key,'U>
66-
67-
static member ``<*>`` (struct (f: IReadOnlyDictionary<'Key,_>, x: IReadOnlyDictionary<'Key,'T>) , _output: IReadOnlyDictionary<'Key,'U> , [<Optional>]_mthd: Apply) : IReadOnlyDictionary<'Key,'U> =
68-
let dct = Dictionary ()
69-
for KeyValue(k, vf) in f do
70-
match x.TryGetValue k with
71-
| true, vx -> dct.Add (k, vf vx)
72-
| _ -> ()
73-
dct :> IReadOnlyDictionary<'Key,'U>
45+
static member ``<*>`` (struct (f: Map<'Key,_> , x: Map<'Key,'T> ) , _output: Map<'Key,'U> , [<Optional>]_mthd: Apply) : Map<'Key,'U> = Map.apply f x
46+
static member ``<*>`` (struct (f: Dictionary<'Key,_> , x: Dictionary<'Key,'T> ) , _output: Dictionary<'Key,'U> , [<Optional>]_mthd: Apply) : Dictionary<'Key,'U> = Dictionary.apply f x
47+
static member ``<*>`` (struct (f: IDictionary<'Key,_> , x: IDictionary<'Key,'T> ) , _output: IDictionary<'Key,'U> , [<Optional>]_mthd: Apply) : IDictionary<'Key,'U> = Dict.apply f x
48+
static member ``<*>`` (struct (f: IReadOnlyDictionary<'Key,_>, x: IReadOnlyDictionary<'Key,'T>) , _output: IReadOnlyDictionary<'Key,'U>, [<Optional>]_mthd: Apply) : IReadOnlyDictionary<'Key,'U> = IReadOnlyDictionary.apply f x
7449

7550
#if !FABLE_COMPILER
76-
static member ``<*>`` (struct (f: Expr<'T->'U>, x: Expr<'T>), _output: Expr<'U>, [<Optional>]_mthd: Apply) = Expr.Cast<'U> (Expr.Application (f, x))
51+
static member ``<*>`` (struct (f: Expr<'T->'U>, x: Expr<'T>), _output: Expr<'U>, [<Optional>]_mthd: Apply) = Expr.Cast<'U> (Expr.Application (f, x))
7752
#endif
78-
static member ``<*>`` (struct (f: ('T->'U) ResizeArray, x: 'T ResizeArray), _output: 'U ResizeArray, [<Optional>]_mthd: Apply) = ResizeArray.apply f x : 'U ResizeArray
53+
static member ``<*>`` (struct (f: ('T->'U) ResizeArray, x: 'T ResizeArray), _output: 'U ResizeArray, [<Optional>]_mthd: Apply) = ResizeArray.apply f x : 'U ResizeArray
7954

8055
static member inline Invoke (f: '``Applicative<'T -> 'U>``) (x: '``Applicative<'T>``) : '``Applicative<'U>`` =
8156
let inline call (mthd : ^M, input1: ^I1, input2: ^I2, output: ^R) =

src/FSharpPlus/Control/Foldable.fs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ type FoldMap =
147147
static member inline FoldMap (x: Set<_> , f, [<Optional>]_impl: FoldMap) = Seq.fold (fun x y -> Plus.Invoke x (f y)) (Zero.Invoke ()) x
148148
static member inline FoldMap (x: _ [] , f, [<Optional>]_impl: FoldMap) = Array.fold (fun x y -> Plus.Invoke x (f y)) (Zero.Invoke ()) x
149149

150+
static member inline FoldMap (x: Map<_, _> , f, [<Optional>]_impl: FoldMap) = Map.fold (fun x _ y -> Plus.Invoke x (f y)) (Zero.Invoke ()) x
151+
static member inline FoldMap (x: IDictionary<_, _> , f, [<Optional>]_impl: FoldMap) = Dict.fold (fun x _ y -> Plus.Invoke x (f y)) (Zero.Invoke ()) x
152+
static member inline FoldMap (x: IReadOnlyDictionary<_, _>, f, [<Optional>]_impl: FoldMap) = IReadOnlyDictionary.fold (fun x _ y -> Plus.Invoke x (f y)) (Zero.Invoke ()) x
153+
150154
static member inline Invoke (f: 'T->'Monoid) (x: '``Foldable'<T>``) : 'Monoid =
151155
let inline call_2 (a: ^a, b: ^b, f) = ((^a or ^b) : (static member FoldMap : _*_*_ -> _) b, f, a)
152156
let inline call (a: 'a, b: 'b, f) = call_2 (a, b, f)
@@ -185,6 +189,9 @@ type Fold =
185189
static member Fold (x: list<_> , f, z , [<Optional>]_impl: Fold ) = List.fold f z x
186190
static member Fold (x: Set<_> , f, z , [<Optional>]_impl: Fold ) = Set.fold f z x
187191
static member Fold (x: _ [] , f, z , [<Optional>]_impl: Fold ) = Array.fold f z x
192+
static member Fold (x: Map<_,_> , f, z , [<Optional>]_impl: Fold ) = Map.fold (fun s _ -> f s) z x
193+
static member Fold (x: IDictionary<_,_> , f, z , [<Optional>]_impl: Fold ) = Dict.fold (fun s _ -> f s) z x
194+
static member Fold (x: IReadOnlyDictionary<_,_>, f, z , [<Optional>]_impl: Fold ) = IReadOnlyDictionary.fold (fun s _ -> f s) z x
188195

189196
static member inline Invoke (folder: 'State->'T->'State) (state: 'State) (foldable: '``Foldable'<T>``) : 'State =
190197
let inline call_2 (a: ^a, b: ^b, f, z) = ((^a or ^b) : (static member Fold : _*_*_*_ -> _) b, f, z, a)

src/FSharpPlus/Control/Functor.fs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,13 @@ type Unzip =
149149
static member inline Unzip ((source: '``Functor<'T * 'U>`` , _output: '``Functor<'T>`` * '``Functor<'U>`` ) , _mthd: Default1) = (^``Functor<'T * 'U>``: (static member Unzip : _->_) source) : '``Functor<'T>`` * '``Functor<'U>``
150150
static member inline Unzip (( _ : ^t when ^t: null and ^t: struct , _ ) , _ ) = ()
151151

152-
static member Unzip ((source: Lazy<'T * 'U> , _output: Lazy<'T> * Lazy<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
152+
static member Unzip ((source: Lazy<'T * 'U> , _output: Lazy<'T> * Lazy<'U> ) , _mthd: Unzip ) = Lazy.map fst source, Lazy.map snd source
153153

154154
#if !FABLE_COMPILER
155-
static member Unzip ((source: Task<'T * 'U> , _output: Task<'T> * Task<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
155+
static member Unzip ((source: Task<'T * 'U> , _output: Task<'T> * Task<'U> ) , _mthd: Unzip ) = Task.map fst source, Task.map snd source
156156
#endif
157157
#if !FABLE_COMPILER
158-
static member Unzip ((source: ValueTask<'T * 'U> , _output: ValueTask<'T> * ValueTask<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
158+
static member Unzip ((source: ValueTask<'T * 'U> , _output: ValueTask<'T> * ValueTask<'U> ) , _mthd: Unzip ) = ValueTask.map fst source, ValueTask.map snd source
159159
#endif
160160
static member Unzip ((source: option<'T * 'U> , _output: option<'T> * option<'U> ) , _mthd: Unzip ) = Option.unzip source
161161
static member Unzip ((source: voption<'T * 'U> , _output: voption<'T> * voption<'U> ) , _mthd: Unzip ) = ValueOption.unzip source
@@ -167,17 +167,17 @@ type Unzip =
167167
static member Unzip ((struct (m: 'Monoid, t: ('T * 'U)) , _output: struct ('Monoid * 'T) * struct ('Monoid * 'U) ) , _mthd: Unzip ) = struct (m, fst t), struct (m, snd t)
168168
static member Unzip ((source: ('T * 'U) [] , _output: 'T [] * 'U [] ) , _mthd: Unzip ) = Array.unzip source
169169
#if !FABLE_COMPILER
170-
static member Unzip ((source: ('T * 'U) [,] , _output: 'T [,] * 'U [,] ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
171-
static member Unzip ((source: ('T * 'U) [,,] , _output: 'T [,,] * 'U [,,] ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
172-
static member Unzip ((source: ('T * 'U) [,,,] , _output: 'T [,,,] * 'U [,,,] ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
170+
static member Unzip ((source: ('T * 'U) [,] , _output: 'T [,] * 'U [,] ) , _mthd: Unzip ) = Array2D.map fst source, Array2D.map snd source
171+
static member Unzip ((source: ('T * 'U) [,,] , _output: 'T [,,] * 'U [,,] ) , _mthd: Unzip ) = Array3D.map fst source, Array3D.map snd source
172+
static member Unzip ((source: ('T * 'U) [,,,] , _output: 'T [,,,] * 'U [,,,] ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
173173
#endif
174174

175-
static member Unzip ((source: Async<'T * 'U> , _output: Async<'T> * Async<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
175+
static member Unzip ((source: Async<'T * 'U> , _output: Async<'T> * Async<'U> ) , _mthd: Unzip ) = Async.map fst source, Async.map snd source
176176
static member Unzip ((source: Result<'T * 'U, 'E> , _output: Result<'T,'E> * Result<'U,'E> ) , _mthd: Unzip ) = Result.unzip source
177-
static member Unzip ((source: Choice<'T * 'U, 'E> , _output: Choice<'T,'E> * Choice<'U,'E> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
177+
static member Unzip ((source: Choice<'T * 'U, 'E> , _output: Choice<'T,'E> * Choice<'U,'E> ) , _mthd: Unzip ) = Choice.map fst source, Choice.map snd source
178178
static member Unzip ((source: KeyValuePair<'Key, 'T * 'U> , _output: KeyValuePair<_, 'T> * KeyValuePair<_, 'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
179-
static member Unzip ((source: Map<'Key, 'T * 'U> , _output: Map<_, 'T> * Map<_, 'U> ) , _mthd: Unzip ) = Map.unzip source
180-
static member Unzip ((source: Dictionary<'Key, 'T * 'U> , _output: Dictionary<_, 'T> * Dictionary<_, 'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
179+
static member Unzip ((source: Map<'Key, 'T * 'U> , _output: Map<_, 'T> * Map<_, 'U> ) , _mthd: Unzip ) = Map.unzip source
180+
static member Unzip ((source: Dictionary<'Key, 'T * 'U> , _output: Dictionary<_, 'T> * Dictionary<_, 'U> ) , _mthd: Unzip ) = Dictionary.unzip source
181181

182182
#if !FABLE_COMPILER
183183
static member Unzip ((source: Expr<'T * 'U> , _output: Expr<'T> * Expr<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
@@ -187,10 +187,10 @@ type Unzip =
187187

188188
static member Unzip ((source: seq<'T * 'U> , _output: seq<'T> * seq<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
189189

190-
static member Unzip ((source: IEnumerator<'T * 'U> , _output: IEnumerator<'T> * ResizeArray<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
190+
static member Unzip ((source: IEnumerator<'T * 'U> , _output: IEnumerator<'T> * ResizeArray<'U> ) , _mthd: Unzip ) = Enumerator.map fst source, Enumerator.map snd source
191191
static member Unzip ((source: IDictionary<'Key, 'T * 'U> , _output: IDictionary<_,'T> * IDictionary<_,'U> ) , _mthd: Unzip ) = Dict.unzip source
192192
static member Unzip ((source: IReadOnlyDictionary<'Key,'T * 'U> , _output: IReadOnlyDictionary<_,'T> * IReadOnlyDictionary<_,'U>) , _mthd: Unzip ) = IReadOnlyDictionary.unzip source
193-
static member Unzip ((source: IObservable<'T * 'U> , _output: IObservable<'T> * ResizeArray<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
193+
static member Unzip ((source: IObservable<'T * 'U> , _output: IObservable<'T> * ResizeArray<'U> ) , _mthd: Unzip ) = Observable.map fst source, Observable.map snd source
194194

195195

196196

@@ -208,7 +208,7 @@ type Zip =
208208
static member Zip ((x: seq<'T> , y: seq<'U> , _output: seq<'T*'U> ), _mthd: Zip) = Seq.zip x y
209209
static member Zip ((x: IDictionary<'K, 'T> , y: IDictionary<'K,'U> , _output: IDictionary<'K,'T*'U> ), _mthd: Zip) = Dict.zip x y
210210
static member Zip ((x: IReadOnlyDictionary<'K, 'T>, y: IReadOnlyDictionary<'K,'U>, _output: IReadOnlyDictionary<'K,'T*'U>), _mthd: Zip) = IReadOnlyDictionary.zip x y
211-
static member Zip ((x: Dictionary<'K, 'T> , y: Dictionary<'K,'U> , _output: Dictionary<'K,'T*'U> ), _mthd: Zip) = Dict.zip x y :?> Dictionary<'K,'T*'U>
211+
static member Zip ((x: Dictionary<'K, 'T> , y: Dictionary<'K,'U> , _output: Dictionary<'K,'T*'U> ), _mthd: Zip) = Dictionary.zip x y
212212
static member Zip ((x: Map<'K, 'T> , y: Map<'K,'U> , _output: Map<'K,'T*'U> ), _mthd: Zip) = Map.zip x y
213213
static member Zip ((f: 'R -> 'T , g: 'R -> 'U , _output: 'R -> 'T * 'U ), _mthd: Zip) = fun x -> (f x, g x)
214214
static member Zip ((f: Func<'R, 'T> , g: Func<'R, 'U> , _output: Func<'R, 'T * 'U> ), _mthd: Zip) = Func<_,_> (fun x -> (f.Invoke x, g.Invoke x))

0 commit comments

Comments
 (0)