Skip to content

Commit e15be4a

Browse files
committed
+ IReadOnlyDictionary as mapi, choosei, iteri, foldi and traversei
1 parent e79d7ee commit e15be4a

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

src/FSharpPlus/Control/Indexable.fs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ type MapIndexed =
7979
call (Unchecked.defaultof<MapIndexed>, source, mapping)
8080
static member inline InvokeOnInstance (mapping: 'K->'T->'Key) (source: '``Indexable<'T>``) : '``Indexable<'U>`` = (^``Indexable<'T>`` : (static member MapIndexed : _*_->_) source, mapping) : ^``Indexable<'U>``
8181

82-
static member inline MapIndexed (x: seq<'T> , f: int->'T->'U, _impl: Default2) = x |> Seq.mapi f : seq<'U>
82+
type MapIndexed with
83+
static member inline MapIndexed (x: seq<'T> , f: int -> 'T -> 'U, _impl: Default3) = x |> Seq.mapi f : seq<'U>
84+
static member inline MapIndexed (x: IReadOnlyDictionary<'Key, 'T>, f: 'Key -> 'T -> 'U, _impl: Default2) = x |> IReadOnlyDictionary.mapi f : IReadOnlyDictionary<'Key, 'U>
85+
static member inline MapIndexed (_: ^t when ^t: null and ^t: struct, _: 'K->'T->'U, _mthd: Default2) = ()
8386
static member inline MapIndexed (x: ^``I<'T>``, f: 'K->'T->'U , _impl: Default1) : '``I<'U>`` = MapIndexed.InvokeOnInstance f x
8487
static member inline MapIndexed (_: ^t when ^t: null and ^t: struct, _: 'K->'T->'U, _mthd: Default1) = ()
8588

@@ -97,7 +100,10 @@ type ChooseIndexed =
97100
call (Unchecked.defaultof<ChooseIndexed>, source, mapping)
98101
static member inline InvokeOnInstance (mapping: 'K->'T->'U option) (source: '``Indexable<'T>``) : '``Indexable<'U>`` = (^``Indexable<'T>`` : (static member ChooseIndexed : _*_->_) source, mapping) : ^``Indexable<'U>``
99102

100-
static member inline ChooseIndexed (x: seq<'T> , f: int->'T->'U option, _impl: Default2) = x |> Seq.choosei f : seq<'U>
103+
type ChooseIndexed with
104+
static member inline ChooseIndexed (x: seq<'T> , f: int-> 'T -> 'U option, _impl: Default3) = x |> Seq.choosei f : seq<'U>
105+
static member inline ChooseIndexed (x: IReadOnlyDictionary<'Key, 'T>, f: 'Key-> 'T -> 'U option, _impl: Default2) = x |> IReadOnlyDictionary.choose f : IReadOnlyDictionary<'Key, 'U>
106+
static member inline ChooseIndexed (_: ^t when ^t: null and ^t: struct, _: 'K->'T->'U option, _mthd: Default2) = ()
101107
static member inline ChooseIndexed (x: ^``I<'T>``, f: 'K->'T->'U option, _impl: Default1) : '``I<'U>`` = ChooseIndexed.InvokeOnInstance f x
102108
static member inline ChooseIndexed (_: ^t when ^t: null and ^t: struct, _: 'K->'T->'U option, _mthd: Default1) = ()
103109

@@ -113,7 +119,10 @@ type IterateIndexed =
113119
call (Unchecked.defaultof<IterateIndexed>, source, action) : unit
114120
static member inline InvokeOnInstance (action: 'K->'T->unit) (source: '``Indexable<'T>``) = (^``Indexable<'T>`` : (static member IterateIndexed : _*_->unit) source, action)
115121

116-
static member inline IterateIndexed (x: seq<'T> , f: int->'T->unit , _impl: Default2) = Seq.iteri f x
122+
type IterateIndexed with
123+
static member inline IterateIndexed (x: seq<'T> , f: int -> 'T-> unit, _impl: Default3) = Seq.iteri f x
124+
static member inline IterateIndexed (x: IReadOnlyDictionary<'Key, 'T>, f: 'Key -> 'T-> unit, _impl: Default2) = IReadOnlyDictionary.iter f x
125+
static member inline IterateIndexed (_: ^t when ^t: null and ^t: struct, _: 'K->'T->'U, _mthd: Default2) = ()
117126
static member inline IterateIndexed (x: ^``I<'T>``, f: 'K->'T->unit , _impl: Default1) = IterateIndexed.InvokeOnInstance f x
118127
static member inline IterateIndexed (_: ^t when ^t: null and ^t: struct, _: 'K->'T->'U, _mthd: Default1) = ()
119128

@@ -131,7 +140,10 @@ type FoldIndexed =
131140
call (Unchecked.defaultof<FoldIndexed>, foldable, folder, state)
132141
static member inline InvokeOnInstance (folder: 'State->'Key->'T->'State) (state: 'State) (source: '``Indexable<'T>``) : 'State = (^``Indexable<'T>`` : (static member FoldIndexed : _*_*_->_) source, folder, state) : 'State
133142

134-
static member inline FoldIndexed (x: seq<_> , f: 'State->int->'T->'State , z:'State, _impl: Default2) = x |> Seq.fold (fun (p, i) t -> (f p i t, i + 1)) (z, 0) |> fst
143+
type FoldIndexed with
144+
static member inline FoldIndexed (x: seq<_> , f: 'State->int->'T->'State , z:'State, _impl: Default3) = x |> Seq.fold (fun (p, i) t -> (f p i t, i + 1)) (z, 0) |> fst
145+
static member FoldIndexed (x: IReadOnlyDictionary<'Key, 'T>, f, z, _impl: Default2) = IReadOnlyDictionary.fold f z x
146+
static member inline FoldIndexed (_: ^t when ^t: null and ^t: struct, _: 'State->'Key->'T->'State, _:'S, _mthd: Default2) = ()
135147
static member inline FoldIndexed (x: ^``I<'T>``, f: 'State->'Key->'T->'State , z:'State, _impl: Default1) : 'State = FoldIndexed.InvokeOnInstance f z x
136148
static member inline FoldIndexed (_: ^t when ^t: null and ^t: struct, _: 'State->'Key->'T->'State, _:'S, _mthd: Default1) = ()
137149

@@ -147,16 +159,22 @@ type TraverseIndexed =
147159
let insert_f k x ys = Map.Invoke (Map.add k) (f k x) <*> ys
148160
Map.foldBack insert_f t (result Map.empty)
149161

150-
static member inline InvokeOnInstance (f: 'Key -> 'T -> '``Functor<'U>``) (t: '``Indexable<'T>``) : '``Functor<'Indexable<'U>>`` = (^``Indexable<'T>`` : (static member TraverseIndexed: _*_->_) t,f) : '``Functor<'Indexable<'U>>``
151-
152-
static member inline TraverseIndexed (t: seq<'T>, f: int -> 'T -> '``Functor<'U>``, [<Optional>]_output: '``Functor<seq<'U>>``, [<Optional>]_impl: Default2) : '``Functor<seq<'U>>`` = Traverse.Invoke (fun (i, x) -> f i x) (Seq.indexed t)
153-
static member inline TraverseIndexed (t: ^``I<'T>``, f: 'Index -> 'T -> '``Functor<'U>``, [<Optional>]_output: '``Functor<'I<'U>>``, [<Optional>]_impl: Default1) : '``Functor<'I<'U>>`` = TraverseIndexed.InvokeOnInstance f t : '``Functor<'I<'U>>``
154-
static member inline TraverseIndexed (_: ^t when ^t: null and ^t: struct, _: 'Index -> 'T -> '``Functor<'U>``, _: 'R, _mthd: Default1) = id
155162

156163
static member inline Invoke (f: 'Key -> 'T -> '``Functor<'U>``) (t: '``Indexable<'T>``) : '``Functor<'Indexable<'U>>`` =
157164
let inline call_3 (a: ^a, b: ^b, c: ^c, f) = ((^a or ^b or ^c) : (static member TraverseIndexed : _*_*_*_ -> _) b, f, c, a)
158165
let inline call (a: 'a, b: 'b, f) = call_3 (a, b, Unchecked.defaultof<'r>, f) : 'r
159166
call (Unchecked.defaultof<TraverseIndexed>, t, f)
167+
static member inline InvokeOnInstance (f: 'Key -> 'T -> '``Functor<'U>``) (t: '``Indexable<'T>``) : '``Functor<'Indexable<'U>>`` = (^``Indexable<'T>`` : (static member TraverseIndexed: _*_->_) t,f) : '``Functor<'Indexable<'U>>``
168+
169+
type TraverseIndexed with
170+
static member inline TraverseIndexed (t: seq<'T> , f: int -> 'T -> '``Functor<'U>``, [<Optional>]_output: '``Functor<seq<'U>>``, [<Optional>]_impl: Default3) : '``Functor<seq<'U>>`` = Traverse.Invoke (fun (i, x) -> f i x) (Seq.indexed t)
171+
172+
static member inline TraverseIndexed (t: IReadOnlyDictionary<'Key, 'T>, f: 'Key -> 'T -> '``Functor<'U>``, [<Optional>]_output: '``Functor<seq<'U>>``, [<Optional>]_impl: Default2) : '``Functor<seq<'U>>`` =
173+
let insert_f k x ys = Map.Invoke (IReadOnlyDictionary.add k) (f k x) <*> ys
174+
IReadOnlyDictionary.foldBack insert_f t (result IReadOnlyDictionary.empty)
175+
static member inline TraverseIndexed (t: ^``I<'T>``, f: 'Index -> 'T -> '``Functor<'U>``, [<Optional>]_output: '``Functor<'I<'U>>``, [<Optional>]_impl: Default1) : '``Functor<'I<'U>>`` = TraverseIndexed.InvokeOnInstance f t : '``Functor<'I<'U>>``
176+
177+
static member inline TraverseIndexed (_: ^t when ^t: null and ^t: struct, _: 'Index -> 'T -> '``Functor<'U>``, _: 'R, _mthd: Default1) = id
160178

161179

162180

tests/FSharpPlus.Tests/Indexables.fs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ module Indexables =
6060
Assert.AreEqual (123, foldi (fun a b c -> a + b + c) 0 (seq [20; 40; 60]))
6161
Assert.AreEqual (123, foldi (fun a b c -> a + b + c) 0 [20; 40; 60])
6262
Assert.AreEqual (123, foldi (fun a b c -> a + b + c) 0 (Map.ofSeq [0, 20; 1, 40; 2, 60]))
63+
Assert.AreEqual (123, foldi (fun a b c -> a + b + c) 0 (readOnlyDict [0, 20; 1, 40; 2, 60]))
6364

6465

6566
[<Test>]
@@ -77,4 +78,8 @@ module Indexables =
7778

7879
let r4 = [ ( [0; 0; 0]); ( [1; 1; 1]); ( [2; 2; 2])] |> traversei (fun i v -> if List.forall ((=) i) v then Some (i :: v) else None)
7980
CollectionAssert.AreEqual ([[0; 0; 0; 0]; [1; 1; 1; 1]; [2; 2; 2; 2]], r4.Value)
80-
Assert.IsInstanceOf<Option<int list list>> (Some r4.Value)
81+
Assert.IsInstanceOf<Option<int list list>> (Some r4.Value)
82+
83+
let r5 = readOnlyDict [ (0, [0; 0; 0]); (1, [1; 1; 1]); (2, [2; 2; 2])] |> traversei (fun i v -> if List.forall ((=) i) v then Some (i :: v) else None)
84+
CollectionAssert.AreEqual (readOnlyDict [(0, [0; 0; 0; 0]); (1, [1; 1; 1; 1]); (2, [2; 2; 2; 2])], r5.Value)
85+
Assert.IsInstanceOf<Option<IReadOnlyDictionary<int,int list>>> (Some r5.Value)

0 commit comments

Comments
 (0)