From 5123a3e51fcc731613fc421091cd6b810ca73321 Mon Sep 17 00:00:00 2001
From: Gustavo Leon <1261319+gusty@users.noreply.github.com>
Date: Thu, 26 Nov 2020 11:57:38 +0100
Subject: [PATCH 01/15] +Dict.initInfinite
---
src/FSharpPlus/Extensions/Dict.fs | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/src/FSharpPlus/Extensions/Dict.fs b/src/FSharpPlus/Extensions/Dict.fs
index 490e308d2..f6fdca1ab 100644
--- a/src/FSharpPlus/Extensions/Dict.fs
+++ b/src/FSharpPlus/Extensions/Dict.fs
@@ -161,3 +161,29 @@ module Dict =
| Some v -> dct.Add (k, v)
| None -> ()
dct :> IDictionary<'Key, 'U>
+
+ /// Creates a conceptually infinite dictionay containing the same value for all possible keys.
+ /// The value for all possible keys.
+ let initInfinite<'TKey,'TValue> (source: 'TValue) : IDictionary<'TKey,'TValue> =
+ {
+ new IDictionary<'TKey,'TValue> with
+ member __.TryGetValue (_key: 'TKey, value: byref<'TValue>) = value <- source; true
+ member __.Count = System.Int32.MaxValue
+ member __.ContainsKey (_key: 'TKey) = true
+ member __.GetEnumerator () = Seq.empty.GetEnumerator () :> System.Collections.IEnumerator
+ member __.GetEnumerator () = Seq.empty.GetEnumerator () : IEnumerator>
+ member __.IsReadOnly = true
+ member __.Item
+ with get (_key: 'TKey) : 'TValue = source
+ and set (_key: 'TKey) (_: 'TValue) : unit = raise (System.NotImplementedException())
+
+ member __.Add (_key: 'TKey, _value: 'TValue) : unit = raise (System.NotImplementedException())
+ member __.Add (_item: KeyValuePair<'TKey,'TValue>) : unit = raise (System.NotImplementedException())
+ member __.Clear () : unit = raise (System.NotImplementedException())
+ member __.Contains (_item: KeyValuePair<'TKey,'TValue>) : bool = raise (System.NotImplementedException())
+ member __.CopyTo (_arr: KeyValuePair<'TKey,'TValue> [], _arrayIndex: int) : unit = raise (System.NotImplementedException())
+ member __.Keys : ICollection<'TKey> = raise (System.NotImplementedException())
+ member __.Remove (_key: 'TKey) : bool = raise (System.NotImplementedException())
+ member __.Remove (_item: KeyValuePair<'TKey,'TValue>) : bool = raise (System.NotImplementedException())
+ member __.Values : ICollection<'TValue> = raise (System.NotImplementedException())
+ }
From 6c30108f62de73619b2b9d273ea576c23b1b7783 Mon Sep 17 00:00:00 2001
From: Gustavo Leon <1261319+gusty@users.noreply.github.com>
Date: Thu, 26 Nov 2020 11:59:39 +0100
Subject: [PATCH 02/15] + Dict overload for Return
---
src/FSharpPlus/Control/Monad.fs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/FSharpPlus/Control/Monad.fs b/src/FSharpPlus/Control/Monad.fs
index cfbc24936..68e7f2467 100644
--- a/src/FSharpPlus/Control/Monad.fs
+++ b/src/FSharpPlus/Control/Monad.fs
@@ -136,6 +136,7 @@ type Return =
static member Return (_: 'a Async , _: Return ) = fun (x: 'a) -> async.Return x
static member Return (_: Result<'a,'e> , _: Return ) = fun x -> Ok x : Result<'a,'e>
static member Return (_: Choice<'a,'e> , _: Return ) = fun x -> Choice1Of2 x : Choice<'a,'e>
+ static member Return (_: IDictionary<'k,'t>, _: Return) = fun x -> Dict.initInfinite x : IDictionary<'k,'t>
static member Return (_: Expr<'a> , _: Return ) = fun x -> Expr.Cast<'a> (Expr.Value (x: 'a))
static member Return (_: ResizeArray<'a>, _: Return ) = fun x -> ResizeArray<'a> (Seq.singleton x)
@@ -276,4 +277,4 @@ type Using with
static member inline Using (resource: 'T when 'T :> IDisposable, body: 'T -> '``Monad<'U>`` , _: Using ) = Using.InvokeOnInstance resource body : '``Monad<'U>``
static member inline Using (_ , _ : 'a -> ^t when ^t : null and ^t: struct , _: Using ) = ()
- #endif
\ No newline at end of file
+ #endif
From 0bd3646a7f8b7904378606c06baf88e05ad2a37a Mon Sep 17 00:00:00 2001
From: Gustavo Leon <1261319+gusty@users.noreply.github.com>
Date: Thu, 26 Nov 2020 12:01:14 +0100
Subject: [PATCH 03/15] +Dict overload for <*>
---
src/FSharpPlus/Control/Applicative.fs | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/FSharpPlus/Control/Applicative.fs b/src/FSharpPlus/Control/Applicative.fs
index d9e1db180..fc7a569fe 100644
--- a/src/FSharpPlus/Control/Applicative.fs
+++ b/src/FSharpPlus/Control/Applicative.fs
@@ -47,6 +47,14 @@ type Apply =
| true, vx -> dct.Add (k, vf vx)
| _ -> ()
dct
+
+ static member ``<*>`` (f: IDictionary<'Key,_>, x: IDictionary<'Key,'T> , []_output: IDictionary<'Key,'U> , []_mthd: Apply) : IDictionary<'Key,'U> =
+ let dct = Dictionary ()
+ for KeyValue(k, vx) in x do
+ match f.TryGetValue k with
+ | true, vf -> dct.Add (k, vf vx)
+ | _ -> ()
+ dct :> IDictionary<'Key,'U>
static member ``<*>`` (f: Expr<'T->'U>, x: Expr<'T>, []_output: Expr<'U>, []_mthd: Apply) = Expr.Cast<'U> (Expr.Application (f, x))
static member ``<*>`` (f: ('T->'U) ResizeArray, x: 'T ResizeArray, []_output: 'U ResizeArray, []_mthd: Apply) = ResizeArray.apply f x : 'U ResizeArray
@@ -131,4 +139,4 @@ type IsLeftZero with
static member inline IsLeftZero (t: ref<'``Applicative<'T>``> , _mthd: Default1) = (^``Applicative<'T>`` : (static member IsLeftZero : _ -> _) t.Value)
static member inline IsLeftZero (_: ref< ^t> when ^t: null and ^t: struct, _: Default1) = ()
-#endif
\ No newline at end of file
+#endif
From 3407b816bff47aa0d54d9cebb7461b545c5aba32 Mon Sep 17 00:00:00 2001
From: Gustavo Leon <1261319+gusty@users.noreply.github.com>
Date: Fri, 27 Nov 2020 09:22:49 +0100
Subject: [PATCH 04/15] Implement Values and Contains
---
src/FSharpPlus/Extensions/Dict.fs | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/FSharpPlus/Extensions/Dict.fs b/src/FSharpPlus/Extensions/Dict.fs
index f6fdca1ab..57655113e 100644
--- a/src/FSharpPlus/Extensions/Dict.fs
+++ b/src/FSharpPlus/Extensions/Dict.fs
@@ -165,14 +165,32 @@ module Dict =
/// Creates a conceptually infinite dictionay containing the same value for all possible keys.
/// The value for all possible keys.
let initInfinite<'TKey,'TValue> (source: 'TValue) : IDictionary<'TKey,'TValue> =
- {
+
+ let icollection value =
+ {
+ new ICollection<'t> with
+ member __.Contains (item: 't) = obj.ReferenceEquals (item, value)
+ member __.GetEnumerator () = (Seq.initInfinite (fun _ -> value)).GetEnumerator () :> System.Collections.IEnumerator
+ member __.GetEnumerator () = (Seq.initInfinite (fun _ -> value)).GetEnumerator () : IEnumerator<'t>
+ member __.IsReadOnly = true
+
+ member __.Add (_item: 't) : unit = raise (System.NotImplementedException())
+ member __.Clear () : unit = raise (System.NotImplementedException())
+ member __.CopyTo (_array: 't [], _arrayIndex: int) : unit = raise (System.NotImplementedException())
+ member __.Count : int = raise (System.NotImplementedException())
+ member __.Remove (_item: 't): bool = raise (System.NotImplementedException())
+ }
+
+ {
new IDictionary<'TKey,'TValue> with
member __.TryGetValue (_key: 'TKey, value: byref<'TValue>) = value <- source; true
member __.Count = System.Int32.MaxValue
member __.ContainsKey (_key: 'TKey) = true
+ member __.Contains (item: KeyValuePair<'TKey,'TValue>) = obj.ReferenceEquals (item.Value, source)
member __.GetEnumerator () = Seq.empty.GetEnumerator () :> System.Collections.IEnumerator
member __.GetEnumerator () = Seq.empty.GetEnumerator () : IEnumerator>
member __.IsReadOnly = true
+ member __.Values = icollection source
member __.Item
with get (_key: 'TKey) : 'TValue = source
and set (_key: 'TKey) (_: 'TValue) : unit = raise (System.NotImplementedException())
@@ -180,10 +198,8 @@ module Dict =
member __.Add (_key: 'TKey, _value: 'TValue) : unit = raise (System.NotImplementedException())
member __.Add (_item: KeyValuePair<'TKey,'TValue>) : unit = raise (System.NotImplementedException())
member __.Clear () : unit = raise (System.NotImplementedException())
- member __.Contains (_item: KeyValuePair<'TKey,'TValue>) : bool = raise (System.NotImplementedException())
member __.CopyTo (_arr: KeyValuePair<'TKey,'TValue> [], _arrayIndex: int) : unit = raise (System.NotImplementedException())
member __.Keys : ICollection<'TKey> = raise (System.NotImplementedException())
member __.Remove (_key: 'TKey) : bool = raise (System.NotImplementedException())
member __.Remove (_item: KeyValuePair<'TKey,'TValue>) : bool = raise (System.NotImplementedException())
- member __.Values : ICollection<'TValue> = raise (System.NotImplementedException())
}
From 25c00cdc00e2b9bf9a9cd3f945ee7dfa45ef2273 Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Fri, 4 Jun 2021 19:56:19 +0200
Subject: [PATCH 05/15] fix enumeration + tests
---
src/FSharpPlus/Extensions/Dict.fs | 4 ++--
tests/FSharpPlus.Tests/General.fs | 12 ++++++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/FSharpPlus/Extensions/Dict.fs b/src/FSharpPlus/Extensions/Dict.fs
index 57655113e..c145e8f6a 100644
--- a/src/FSharpPlus/Extensions/Dict.fs
+++ b/src/FSharpPlus/Extensions/Dict.fs
@@ -187,8 +187,8 @@ module Dict =
member __.Count = System.Int32.MaxValue
member __.ContainsKey (_key: 'TKey) = true
member __.Contains (item: KeyValuePair<'TKey,'TValue>) = obj.ReferenceEquals (item.Value, source)
- member __.GetEnumerator () = Seq.empty.GetEnumerator () :> System.Collections.IEnumerator
- member __.GetEnumerator () = Seq.empty.GetEnumerator () : IEnumerator>
+ member __.GetEnumerator () = invalidOp "Key set is potentially infinite." : System.Collections.IEnumerator
+ member __.GetEnumerator () = invalidOp "Key set is potentially infinite." : IEnumerator>
member __.IsReadOnly = true
member __.Values = icollection source
member __.Item
diff --git a/tests/FSharpPlus.Tests/General.fs b/tests/FSharpPlus.Tests/General.fs
index 0d33480c0..e97a298ac 100644
--- a/tests/FSharpPlus.Tests/General.fs
+++ b/tests/FSharpPlus.Tests/General.fs
@@ -436,6 +436,18 @@ module Functor =
Assert.IsInstanceOf