Repository: gcanti/fp-ts
Pull request #1084 (2020-01-12 07:43:14)

`foldMap` and `foldMapWithIndex` now require a `Semigroup` instead of…
… a `Monoid`



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cc4180c2..b8ebdbf3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,7 +17,9 @@ high state of flux, you're at risk of it changing without notice.
 # 2.4.1
 
 - **Polish**
-  - add overloading to `NEA.group` managing non empty arrays, closes #831 (@gcanti)
+  - `NonEmptyArray`
+    - add overloading to `group` managing non empty arrays, closes #831 (@gcanti)
+    - `foldMap` and `foldMapWithIndex` now require a `Semigroup` instead of a `Monoid` (@gcanti)
 
 # 2.4.0
 
diff --git a/docs/modules/NonEmptyArray.ts.md b/docs/modules/NonEmptyArray.ts.md
index 7987cc38..e253f8cd 100644
--- a/docs/modules/NonEmptyArray.ts.md
+++ b/docs/modules/NonEmptyArray.ts.md
@@ -537,7 +537,7 @@ Added in v2.0.0
 **Signature**
 
 ```ts
-;<M>(M: Monoid<M>) => <A>(f: (a: A) => M) => (fa: NonEmptyArray<A>) => M
+;<S>(S: Semigroup<S>) => <A>(f: (a: A) => S) => (fa: NonEmptyArray<A>) => S
 ```
 
 Added in v2.0.0
@@ -547,7 +547,7 @@ Added in v2.0.0
 **Signature**
 
 ```ts
-;<M>(M: Monoid<M>) => <A>(f: (i: number, a: A) => M) => (fa: NonEmptyArray<A>) => M
+;<S>(S: Semigroup<S>) => <A>(f: (i: number, a: A) => S) => (fa: NonEmptyArray<A>) => S
 ```
 
 Added in v2.0.0
diff --git a/src/NonEmptyArray.ts b/src/NonEmptyArray.ts
index aad53315..526c92ee 100644
--- a/src/NonEmptyArray.ts
+++ b/src/NonEmptyArray.ts
@@ -356,8 +356,6 @@ const {
   duplicate,
   extend,
   flatten,
-  foldMap,
-  foldMapWithIndex,
   map,
   mapWithIndex,
   reduce,
@@ -366,6 +364,12 @@ const {
   reduceWithIndex
 } = pipeable(nonEmptyArray)
 
+const foldMapWithIndex = <S>(S: Semigroup<S>) => <A>(f: (i: number, a: A) => S) => (fa: NonEmptyArray<A>) =>
+  fa.slice(1).reduce((s, a, i) => S.concat(s, f(i + 1, a)), f(0, fa[0]))
+
+const foldMap = <S>(S: Semigroup<S>) => <A>(f: (a: A) => S) => (fa: NonEmptyArray<A>) =>
+  fa.slice(1).reduce((s, a) => S.concat(s, f(a)), f(fa[0]))
+
 export {
   /**
    * @since 2.0.0


Test patch:
diff --git a/test/NonEmptyArray.ts b/test/NonEmptyArray.ts
index 0db6eee3..59d3646b 100644
--- a/test/NonEmptyArray.ts
+++ b/test/NonEmptyArray.ts
@@ -5,10 +5,13 @@ import { identity } from '../src/function'
 import * as I from '../src/Identity'
 import { fold, monoidString, monoidSum } from '../src/Monoid'
 import {
+  concat,
   cons,
   copy,
   filter,
   filterWithIndex,
+  foldMap,
+  foldMapWithIndex,
   fromArray,
   getEq,
   getSemigroup,
@@ -17,23 +20,23 @@ import {
   groupBy,
   groupSort,
   head,
+  init,
   insertAt,
   last,
   max,
   min,
   modifyAt,
   nonEmptyArray,
+  NonEmptyArray,
   reverse,
   snoc,
   sort,
   tail,
-  updateAt,
-  NonEmptyArray,
-  init,
-  concat
+  updateAt
 } from '../src/NonEmptyArray'
 import { isSome, none, option, some } from '../src/Option'
 import { ordNumber } from '../src/Ord'
+import { semigroupSum } from '../src/Semigroup'
 import { showString } from '../src/Show'
 
 describe('NonEmptyArray', () => {
@@ -330,4 +333,16 @@ describe('NonEmptyArray', () => {
       ['a', 'b']
     )
   })
+
+  it('foldMap', () => {
+    const f = foldMap(semigroupSum)((s: string) => s.length)
+    assert.deepStrictEqual(f(['a']), 1)
+    assert.deepStrictEqual(f(['a', 'bb']), 3)
+  })
+
+  it('foldMapWithIndex', () => {
+    const f = foldMapWithIndex(semigroupSum)((i: number, s: string) => s.length + i)
+    assert.deepStrictEqual(f(['a']), 1)
+    assert.deepStrictEqual(f(['a', 'bb']), 4)
+  })
 })