Skip to content

Commit 7f93d61

Browse files
committed
Fix bug in foldi for Map
1 parent 54960d7 commit 7f93d61

File tree

5 files changed

+81
-48
lines changed

5 files changed

+81
-48
lines changed

src/FSharpPlus/Control/Indexable.fs

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ type FoldIndexed =
123123
inherit Default1
124124
static member FoldIndexed (x: list<_> , f, z, _impl: FoldIndexed) = x |> List.fold (fun (p, i) t -> (f p i t, i + 1)) (z, 0) |> fst
125125
static member FoldIndexed (x: _ [] , f, z, _impl: FoldIndexed) = x |> Array.fold (fun (p, i) t -> (f p i t, i + 1)) (z, 0) |> fst
126-
static member FoldIndexed (_: Map<'k,'t>, f, z, _impl: FoldIndexed) = Map.fold f z
126+
static member FoldIndexed (x: Map<'k,'t>, f, z, _impl: FoldIndexed) = Map.fold f z x
127127

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

tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<Compile Include="Monoid.fs" />
2222
<Compile Include="Parsing.fs" />
2323
<Compile Include="Traversals.fs" />
24+
<Compile Include="Indexables.fs" />
2425
<Compile Include="Validations.fs" />
2526
<Compile Include="Task.fs" />
2627
<Compile Include="ValueTask.fs" />

tests/FSharpPlus.Tests/General.fs

-42
Original file line numberDiff line numberDiff line change
@@ -915,48 +915,6 @@ module Foldable =
915915
areEqual sb' None
916916
()
917917

918-
module Indexable =
919-
[<Test>]
920-
let testCompileAndExecuteItem () =
921-
922-
let a = Map.ofSeq [1, "one"; 2, "two"]
923-
let _ = item 1 a
924-
925-
let b = dict [1, "one"; 2, "two"]
926-
let _ = item 1 b
927-
928-
let c = "two"
929-
let _ = item 1 c
930-
931-
let d = System.Text.StringBuilder "one"
932-
let _ = item 1 d
933-
934-
let e = array2D [[1;2];[3;4];[5;6]]
935-
let _ = item (1, 1) e
936-
937-
let f = [1, "one"; 2, "two"]
938-
let _ = item 1 f
939-
940-
let g = [|1, "one"; 2, "two"|]
941-
let _ = item 1 g
942-
943-
let h = ResizeArray [1, "one"; 2, "two"]
944-
let _ = item 1 h
945-
946-
let i = Array3D.create 3 2 2 0
947-
let _ = item (1, 1, 1) i
948-
949-
let j = Array4D.create 3 2 2 3 0
950-
let _ = item (1, 1, 1, 1) j
951-
952-
let k = NonEmptyMap.Create (("a", 1), ("b", 2))
953-
let _ = item "b" k
954-
955-
// This doesn't intentionally compile: seq is not Indexable. Not all foldables are Indexable, for example a Set is foldable but not Indexable. For seq use nth instead.
956-
// let f = seq [1, "one"; 2, "two"]
957-
// let _ = item 1 f
958-
959-
()
960918

961919
[<Test>]
962920
let testCompileAndExecuteTryItem () =

tests/FSharpPlus.Tests/Indexables.fs

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
namespace FSharpPlus.Tests
2+
3+
#nowarn "686"
4+
5+
open System
6+
open System.Collections.Generic
7+
open FSharpPlus
8+
open FSharpPlus.Data
9+
open FSharpPlus.Control
10+
open NUnit.Framework
11+
open Helpers
12+
13+
14+
module Indexables =
15+
16+
[<Test>]
17+
let testCompileAndExecuteItem () =
18+
19+
let a = Map.ofSeq [1, "one"; 2, "two"]
20+
let _ = item 1 a
21+
22+
let b = dict [1, "one"; 2, "two"]
23+
let _ = item 1 b
24+
25+
let c = "two"
26+
let _ = item 1 c
27+
28+
let d = System.Text.StringBuilder "one"
29+
let _ = item 1 d
30+
31+
let e = array2D [[1;2];[3;4];[5;6]]
32+
let _ = item (1, 1) e
33+
34+
let f = [1, "one"; 2, "two"]
35+
let _ = item 1 f
36+
37+
let g = [|1, "one"; 2, "two"|]
38+
let _ = item 1 g
39+
40+
let h = ResizeArray [1, "one"; 2, "two"]
41+
let _ = item 1 h
42+
43+
let i = Array3D.create 3 2 2 0
44+
let _ = item (1, 1, 1) i
45+
46+
let j = Array4D.create 3 2 2 3 0
47+
let _ = item (1, 1, 1, 1) j
48+
49+
let k = NonEmptyMap.Create (("a", 1), ("b", 2))
50+
let _ = item "b" k
51+
52+
// This doesn't intentionally compile: seq is not Indexable. Not all foldables are Indexable, for example a Set is foldable but not Indexable. For seq use nth instead.
53+
// let f = seq [1, "one"; 2, "two"]
54+
// let _ = item 1 f
55+
56+
()
57+
58+
[<Test>]
59+
let foldIndexed () =
60+
Assert.AreEqual (123, foldi (fun a b c -> a + b + c) 0 (seq [20; 40; 60]))
61+
Assert.AreEqual (123, foldi (fun a b c -> a + b + c) 0 [20; 40; 60])
62+
63+
64+
[<Test>]
65+
let traverseIndexed () =
66+
let m1 = Map.ofList [(1, [1;1;1]); (2, [2;2;2])]
67+
let r1 = m1 |> traversei (fun _ _ -> None)
68+
let r2 = m1 |> traversei (fun i v -> if List.forall ((=) i) v then Some (i :: v) else None)
69+
AreEqual (None = r1)
70+
CollectionAssert.AreEqual (Map.ofList [(1, [1;1;1;1]); (2, [2;2;2;2])], r2.Value)
71+
Assert.IsInstanceOf<Option<Map<int,int list>>> (Some r2.Value)
72+
73+
let r3 = seq [ ( [0;0;0]); ( [1;1;1]); ( [2;2;2])] |> traversei (fun i v -> if List.forall ((=) i) v then Some (i :: v) else None)
74+
CollectionAssert.AreEqual (seq [[0; 0; 0]; [1; 1; 1]; [2; 2; 2]], r3.Value)
75+
Assert.IsInstanceOf<Option<seq<int list>>> (Some r3.Value)
76+
77+
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)
78+
CollectionAssert.AreEqual ([[0; 0; 0; 0]; [1; 1; 1; 1]; [2; 2; 2; 2]], r4.Value)
79+
Assert.IsInstanceOf<Option<int list list>> (Some r4.Value)

tests/FSharpPlus.Tests/Traversals.fs

-5
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,6 @@ module Traversable =
273273
CollectionAssert.AreEqual (r2.Value, m)
274274

275275
let m1 = Map.ofList [(1, [1;1;1]); (2, [2;2;2])]
276-
let r1 = m1 |> traversei (fun _ _ -> None)
277-
let r2 = m1 |> traversei (fun i v -> if List.forall ((=) i) v then Some (i :: v) else None)
278-
Assert.AreEqual(None, r1)
279-
CollectionAssert.AreEqual (Map.ofList [(1, [1;1;1;1]); (2, [2;2;2;2])], r2.Value)
280-
281276
let expected = [Map.ofList [(1, 1); (2, 2)]; Map.ofList [(1, 1); (2, 2)]; Map.ofList [(1, 1); (2, 2)];
282277
Map.ofList [(1, 1); (2, 2)]; Map.ofList [(1, 1); (2, 2)]; Map.ofList [(1, 1); (2, 2)];
283278
Map.ofList [(1, 1); (2, 2)]; Map.ofList [(1, 1); (2, 2)]; Map.ofList [(1, 1); (2, 2)]]

0 commit comments

Comments
 (0)