Skip to content

Commit d721e0e

Browse files
committed
Use map2
1 parent 1b1a3ee commit d721e0e

File tree

3 files changed

+36
-26
lines changed

3 files changed

+36
-26
lines changed

src/FSharpPlus/Control/Applicative.fs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,7 @@ type Apply =
5757
dct
5858

5959
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>
60+
Dict.map2 id f x
6661

6762
static member ``<*>`` (struct (f: IReadOnlyDictionary<'Key,_>, x: IReadOnlyDictionary<'Key,'T>) , _output: IReadOnlyDictionary<'Key,'U> , [<Optional>]_mthd: Apply) : IReadOnlyDictionary<'Key,'U> =
6863
let dct = Dictionary ()

src/FSharpPlus/Control/ZipApplicative.fs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ type Pure =
2929
let inline call (mthd: ^M, output: ^R) = ((^M or ^R) : (static member Pure : _*_ -> _) output, mthd)
3030
call (Unchecked.defaultof<Pure>, Unchecked.defaultof<'``ZipApplicative<'T>``>) x
3131

32-
static member Pure (_: seq<'a> , _: Default2 ) = fun x -> Seq.initInfinite (fun _ -> x) : seq<'a>
33-
static member Pure (_: IEnumerator<'a> , _: Default2 ) = fun x -> Enumerator.upto None (fun _ -> x) : IEnumerator<'a>
32+
static member Pure (_: seq<'a> , _: Default4 ) = fun x -> Seq.initInfinite (fun _ -> x) : seq<'a>
33+
static member Pure (_: IEnumerator<'a> , _: Default3 ) = fun x -> Enumerator.upto None (fun _ -> x) : IEnumerator<'a>
34+
static member Pure (_: IDictionary<'k,'t>, _: Default2) = fun x -> Dict.initInfinite x: IDictionary<'k,'t>
35+
#if (!FABLE_COMPILER_3) // TODO Dummy overload for now
36+
static member Pure (_: IReadOnlyDictionary<'k,'t>, _: Default3) = fun x -> readOnlyDict [Unchecked.defaultof<'k>, x] : IReadOnlyDictionary<'k,'t>
37+
#endif
3438
static member inline Pure (_: 'R , _: Default1 ) = fun (x: 'T) -> Pure.InvokeOnInstance x : 'R
3539
static member Pure (x: Lazy<'a> , _: Pure) = Return.Return (x, Unchecked.defaultof<Return>) : _ -> Lazy<'a>
3640
#if !FABLE_COMPILER

src/FSharpPlus/Extensions/Dict.fs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,18 @@ module Dict =
128128
///
129129
/// <returns>The mapped dictionary.</returns>
130130
let map mapper (source: IDictionary<'Key, 'T>) =
131-
let dct = Dictionary<'Key, 'U> ()
132-
for KeyValue(k, v) in source do
133-
dct.Add (k, mapper v)
134-
dct :> IDictionary<'Key, 'U>
131+
match source with
132+
| :? DefaultableDict<'Key, 'T> as s ->
133+
let dct = DefaultableDict<'Key, 'U> (mapper s.DefaultValue, Dictionary<'Key, 'U> ())
134+
let dct = dct :> IDictionary<'Key, 'U>
135+
for KeyValue(k, v) in source do
136+
dct.Add (k, mapper v)
137+
dct
138+
| _ ->
139+
let dct = Dictionary<'Key, 'U> ()
140+
for KeyValue(k, v) in source do
141+
dct.Add (k, mapper v)
142+
dct :> IDictionary<'Key, 'U>
135143

136144
/// <summary>Creates a Dictionary value from a pair of Dictionaries, using a function to combine them.</summary>
137145
/// <remarks>Keys that are not present on both dictionaries are dropped.</remarks>
@@ -141,13 +149,21 @@ module Dict =
141149
///
142150
/// <returns>The combined dictionary.</returns>
143151
let map2 mapper (source1: IDictionary<'Key, 'T1>) (source2: IDictionary<'Key, 'T2>) =
144-
let dct = Dictionary<'Key, 'U> ()
145-
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt mapper
146-
for KeyValue(k, vx) in source1 do
147-
match tryGetValue k source2 with
148-
| Some vy -> dct.Add (k, f.Invoke (vx, vy))
149-
| None -> ()
150-
dct :> IDictionary<'Key, 'U>
152+
let map k1 k2 =
153+
let dct = Dictionary<'Key, 'U> ()
154+
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt mapper
155+
for k in set source1.Keys + set source2.Keys do
156+
match tryGetValue k source1, tryGetValue k source2, k1, k2 with
157+
| Some vx, Some vy, _ , _
158+
| None , Some vy, Some vx, _
159+
| Some vx, None , _ , Some vy -> dct.Add (k, f.Invoke (vx, vy))
160+
| _ , _ , _ , _ -> ()
161+
dct :> IDictionary<'Key, 'U>
162+
match source1, source2 with
163+
| (:? DefaultableDict<'Key,'T1> as s1), (:? DefaultableDict<'Key,'T2> as s2) -> initHybrid (mapper s1.DefaultValue s2.DefaultValue) (map (Some s1.DefaultValue) (Some s2.DefaultValue))
164+
| (:? DefaultableDict<'Key,'T1> as s1), _ -> map (Some s1.DefaultValue) None
165+
| _, (:? DefaultableDict<'Key,'T2> as s2) -> map None (Some s2.DefaultValue)
166+
| _, _ -> map None None
151167

152168
/// <summary>Combines values from three dictionaries using mapping function.</summary>
153169
/// <remarks>Keys that are not present on every dictionary are dropped.</remarks>
@@ -185,13 +201,7 @@ module Dict =
185201
/// <param name="source2">The second input dictionary.</param>
186202
///
187203
/// <returns>The tupled dictionary.</returns>
188-
let zip (source1: IDictionary<'Key, 'T1>) (source2: IDictionary<'Key, 'T2>) =
189-
let dct = Dictionary<'Key, 'T1 * 'T2> ()
190-
for KeyValue(k, vx) in source1 do
191-
match tryGetValue k source2 with
192-
| Some vy -> dct.Add (k, (vx, vy))
193-
| None -> ()
194-
dct :> IDictionary<'Key, 'T1 * 'T2>
204+
let zip (source1: IDictionary<'Key, 'T1>) (source2: IDictionary<'Key, 'T2>) = map2 (fun x y -> (x, y)) source1 source2
195205

196206
/// <summary>Splits a dictionary with tuple pair values to two separate dictionaries.</summary>
197207
/// <param name="source">The source dictionary.</param>
@@ -223,6 +233,7 @@ module Dict =
223233
// d :> IDictionary<'Key,'Value>
224234
match source1, source2 with
225235
| (:? DefaultableDict<'Key,'Value> as s1), (:? DefaultableDict<'Key,'Value> as s2) -> initHybrid (combiner s1.DefaultValue s2.DefaultValue) (combine())
236+
| (:? DefaultableDict<'Key,'Value> as s), _ | _, (:? DefaultableDict<'Key,'Value> as s) -> initHybrid s.DefaultValue (combine())
226237
| s, empty | empty, s when empty.Count = 0 -> s
227238
| _, _ -> combine()
228239

0 commit comments

Comments
 (0)