Skip to content

Commit e3b1916

Browse files
authored
+ Bind and Join for dict interfaces (#627)
1 parent 43934c6 commit e3b1916

File tree

4 files changed

+83
-31
lines changed

4 files changed

+83
-31
lines changed

src/FSharpPlus/Control/Monad.fs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,29 @@ type Bind =
5050
| Some v -> yield k, v
5151
| _ -> () })
5252

53-
static member (>>=) (source: Dictionary<'Key,'T>, f: 'T -> Dictionary<'Key,'U>) =
54-
let dct = Dictionary ()
55-
for KeyValue(k, v) in source do
56-
match (f v).TryGetValue (k) with
57-
| true, v -> dct.Add (k, v)
58-
| _ -> ()
59-
dct
53+
static member (>>=) (source: Dictionary<'Key,'T>, f: 'T -> Dictionary<'Key,'U>) =
54+
let dct = Dictionary ()
55+
for KeyValue(k, v) in source do
56+
match (f v).TryGetValue (k) with
57+
| true, v -> dct.Add (k, v)
58+
| _ -> ()
59+
dct
60+
61+
static member (>>=) (source: IDictionary<'Key,'T>, f: 'T -> IDictionary<'Key,'U>) =
62+
let dct = Dictionary ()
63+
for KeyValue(k, v) in source do
64+
match (f v).TryGetValue (k) with
65+
| true, v -> dct.Add (k, v)
66+
| _ -> ()
67+
dct :> IDictionary<'Key,'U>
68+
69+
static member (>>=) (source: IReadOnlyDictionary<'Key,'T>, f: 'T -> IReadOnlyDictionary<'Key,'U>) =
70+
let dct = Dictionary ()
71+
for KeyValue(k, v) in source do
72+
match (f v).TryGetValue (k) with
73+
| true, v -> dct.Add (k, v)
74+
| _ -> ()
75+
dct :> IReadOnlyDictionary<'Key,'U>
6076

6177
static member (>>=) (source: ResizeArray<'T>, f: 'T -> ResizeArray<'U>) = ResizeArray (Seq.bind (f >> seq<_>) source) : ResizeArray<'U>
6278

@@ -114,6 +130,22 @@ type Join =
114130
| _ -> ()
115131
dct
116132

133+
static member Join (x: IDictionary<_, IDictionary<_, _>>, [<Optional>]_output: IDictionary<'Key, 'Value>, [<Optional>]_mthd: Join) : IDictionary<'Key, 'Value> =
134+
let dct = Dictionary ()
135+
for KeyValue(k, v) in x do
136+
match v.TryGetValue (k) with
137+
| true, v -> dct.Add (k, v)
138+
| _ -> ()
139+
dct :> IDictionary<'Key, 'U>
140+
141+
static member Join (x: IReadOnlyDictionary<_, IReadOnlyDictionary<_, _>>, [<Optional>]_output: IReadOnlyDictionary<'Key, 'Value>, [<Optional>]_mthd: Join) : IReadOnlyDictionary<'Key, 'Value> =
142+
let dct = Dictionary ()
143+
for KeyValue(k, v) in x do
144+
match v.TryGetValue (k) with
145+
| true, v -> dct.Add (k, v)
146+
| _ -> ()
147+
dct :> IReadOnlyDictionary<'Key, 'U>
148+
117149
static member Join (x: ResizeArray<ResizeArray<'T>> , [<Optional>]_output: ResizeArray<'T> , [<Optional>]_mthd: Join) = ResizeArray (Seq.bind seq<_> x) : ResizeArray<'T>
118150

119151
static member Join (x: NonEmptySeq<NonEmptySeq<'T>> , [<Optional>]_output: NonEmptySeq<'T> , [<Optional>]_mthd: Join) = NonEmptySeq.concat x : NonEmptySeq<'T>

tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<Compile Include="Data.fs" />
2020
<Compile Include="General.fs" />
2121
<Compile Include="Applicatives.fs" />
22+
<Compile Include="Monads.fs" />
2223
<Compile Include="Splits.fs" />
2324
<Compile Include="Monoid.fs" />
2425
<Compile Include="Parsing.fs" />

tests/FSharpPlus.Tests/General.fs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,30 +1089,6 @@ module IdiomBrackets =
10891089
let res3n4''' = iI (+) (result 2) [1;2] Ii // fails to compile when constraints are not properly defined
10901090
Assert.AreEqual ([3;4], res3n4'' )
10911091
Assert.AreEqual ([3;4], res3n4''')
1092-
1093-
1094-
let output = System.Text.StringBuilder ()
1095-
let append (x: string) = output.Append x |> ignore
1096-
1097-
let v5: Lazy<_> = lazy (append "5"; 5)
1098-
Assert.AreEqual (0, output.Length)
1099-
let fPlus10 x = lazy (append " + 10"; x + 10)
1100-
Assert.AreEqual (0, output.Length)
1101-
let v5plus10 = v5 >>= fPlus10
1102-
Assert.AreEqual (0, output.Length)
1103-
let v15 = v5plus10.Force ()
1104-
Assert.AreEqual ("5 + 10", string output)
1105-
Assert.AreEqual (15, v15)
1106-
1107-
output.Clear () |> ignore
1108-
1109-
let v4ll: Lazy<_> = lazy (append "outer"; lazy (append "inner"; 4))
1110-
Assert.AreEqual (0, output.Length)
1111-
let v4l = join v4ll
1112-
Assert.AreEqual (0, output.Length)
1113-
let v4 = v4l.Force()
1114-
Assert.AreEqual ("outerinner", string output)
1115-
Assert.AreEqual (4, v4)
11161092

11171093

11181094
module Alternative =

tests/FSharpPlus.Tests/Monads.fs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
namespace FSharpPlus.Tests
2+
3+
open System
4+
open System.Collections.ObjectModel
5+
open FSharpPlus
6+
open FSharpPlus.Data
7+
open NUnit.Framework
8+
open Helpers
9+
10+
module Monads =
11+
12+
[<Test>]
13+
let lazies () =
14+
let output = System.Text.StringBuilder ()
15+
let append (x: string) = output.Append x |> ignore
16+
17+
let v5: Lazy<_> = lazy (append "5"; 5)
18+
Assert.AreEqual (0, output.Length)
19+
let fPlus10 x = lazy (append " + 10"; x + 10)
20+
Assert.AreEqual (0, output.Length)
21+
let v5plus10 = v5 >>= fPlus10
22+
Assert.AreEqual (0, output.Length)
23+
let v15 = v5plus10.Force ()
24+
Assert.AreEqual ("5 + 10", string output)
25+
Assert.AreEqual (15, v15)
26+
27+
output.Clear () |> ignore
28+
29+
let v4ll: Lazy<_> = lazy (append "outer"; lazy (append "inner"; 4))
30+
Assert.AreEqual (0, output.Length)
31+
let v4l = join v4ll
32+
Assert.AreEqual (0, output.Length)
33+
let v4 = v4l.Force()
34+
Assert.AreEqual ("outerinner", string output)
35+
Assert.AreEqual (4, v4)
36+
37+
[<Test>]
38+
let mapLikes () =
39+
let r1 = dict [ "a", 1; "b", 2 ; "c", 3 ] >>= fun x -> dict [ "a", x + 10; "c", x + 300; "d", x + 400 ]
40+
CollectionAssert.AreEqual (dict [ "a", 11; "c", 303 ], r1)
41+
42+
let r2 = readOnlyDict [ "a", 1; "b", 2 ; "c", 3 ] >>= fun x -> readOnlyDict [ "a", x + 10; "c", x + 300; "d", x + 400 ]
43+
CollectionAssert.AreEqual (readOnlyDict [ "a", 11; "c", 303 ], r2)

0 commit comments

Comments
 (0)