fp-tsの一覧ページがあまりにも重くなったので、分割
参照元
一覧
Semigroupの内容確認
参考
ファイル名 | import先 | ソースの中身 | declare module がある | importでの参照される数 |
---|---|---|---|---|
Semigroup |
|
interface, function, const のみ | なし | 13 |
満たすべきもの
結合律
(a \cdot b) \cdot c = a \cdot (b \cdot c)
import { describe, it } from 'vitest'
import type { Semigroup } from 'fp-ts/lib/Semigroup'
type Test2<XXX> = {
Test2: XXX
}
type _a = number
type _b = string
type A = Test2<_a>
type B = Test2<_b>
const TestSemigroupTest2a: Semigroup<A> = {
concat: (x, y) => ({
Test2:
x !== undefined && y !== undefined
? x.Test2 + y.Test2
: x !== undefined
? x.Test2
: y !== undefined
? y.Test2
: 0
})
}
const _compare_b = (x: B, y: B) => (x.Test2 > y.Test2 ? 1 : x.Test2 < y.Test2 ? -1 : 0)
const _concat_b = (x: B, y: B) => {
const array = [x, y].sort(_compare_b)
return `${array[0].Test2} - ${array[1].Test2}`
}
const TestSemigroupTest2b: Semigroup<B> = {
concat: (x, y) => ({
Test2:
x !== undefined && y !== undefined
? _concat_b(x, y)
: x !== undefined
? x.Test2
: y !== undefined
? y.Test2
: ''
})
}
describe('fp-ts Tutorial', () => {
it('Semigroup', () => {
// base
const a1: A = { Test2: 123 }
const a2: A = { Test2: 456 }
const a3: A = { Test2: 789 }
const b1: B = { Test2: 'abc' }
const b2: B = { Test2: 'def' }
const b3: B = { Test2: 'ghi' }
// check
console.log(
'concat - check - a1, (a2, a3) - ',
TestSemigroupTest2a.concat(a1, TestSemigroupTest2a.concat(a2, a3))
)
console.log(
'concat - check - (a1, a2), a3 - ',
TestSemigroupTest2a.concat(TestSemigroupTest2a.concat(a1, a2), a3)
)
console.log(
'concat - check - b1, (b2, b3) - ',
TestSemigroupTest2b.concat(b1, TestSemigroupTest2b.concat(b2, b3))
)
console.log(
'concat - check - (b1, b2), b3 - ',
TestSemigroupTest2b.concat(TestSemigroupTest2b.concat(b1, b2), b3)
)
})
})
実行結果
concat - check - a1, (a2, a3) - { Test2: 1368 }
concat - check - (a1, a2), a3 - { Test2: 1368 }
concat - check - b1, (b2, b3) - { Test2: 'abc - def - ghi' }
concat - check - (b1, b2), b3 - { Test2: 'abc - def - ghi' }
Semigroupの法則を満たさないもの
不完全なSemigroupを作成できてしまう
import { describe, it } from 'vitest'
import type { Semigroup } from 'fp-ts/lib/Semigroup'
type Test2<XXX> = {
Test2: XXX
}
type _a = number
type _b = string
type A = Test2<_a>
type B = Test2<_b>
const TestSemigroupTest2a: Semigroup<A> = {
concat: (x, y) => ({
Test2:
x !== undefined && y !== undefined
? x.Test2 + y.Test2 + x.Test2 / 2
: x !== undefined
? x.Test2 + x.Test2 / 2
: y !== undefined
? y.Test2
: 0
})
}
const _compare_b = (x: B, y: B) => (x.Test2 > y.Test2 ? 1 : x.Test2 < y.Test2 ? -1 : 0)
const _concat_b = (x: B, y: B) => {
const array = [x, y].sort(_compare_b)
return `a - ${array[0].Test2} - ${array[1].Test2}`
}
const TestSemigroupTest2b: Semigroup<B> = {
concat: (x, y) => ({
Test2:
x !== undefined && y !== undefined
? _concat_b(x, y)
: x !== undefined
? 'a - ' + x.Test2
: y !== undefined
? y.Test2
: ''
})
}
describe('fp-ts Tutorial', () => {
it('Semigroup', () => {
// base
const a1: A = { Test2: 123 }
const a2: A = { Test2: 456 }
const a3: A = { Test2: 789 }
const b1: B = { Test2: 'abc' }
const b2: B = { Test2: 'def' }
const b3: B = { Test2: 'ghi' }
// check
console.log(
'concat - check - a1, (a2, a3) - ',
TestSemigroupTest2a.concat(a1, TestSemigroupTest2a.concat(a2, a3))
)
console.log(
'concat - check - (a1, a2), a3 - ',
TestSemigroupTest2a.concat(TestSemigroupTest2a.concat(a1, a2), a3)
)
console.log(
'concat - check - b1, (b2, b3) - ',
TestSemigroupTest2b.concat(b1, TestSemigroupTest2b.concat(b2, b3))
)
console.log(
'concat - check - (b1, b2), b3 - ',
TestSemigroupTest2b.concat(TestSemigroupTest2b.concat(b1, b2), b3)
)
})
})
concat - check - a1, (a2, a3) - { Test2: 1657.5 }
concat - check - (a1, a2), a3 - { Test2: 1749.75 }
concat - check - b1, (b2, b3) - { Test2: 'a - a - def - ghi - abc' }
concat - check - (b1, b2), b3 - { Test2: 'a - a - abc - def - ghi' }
Semigroupの利用
import { describe, it } from 'vitest'
import * as S from 'fp-ts/Semigroup'
import type { Semigroup } from 'fp-ts/lib/Semigroup'
import type { Ord } from 'fp-ts/lib/Ord'
type Test2<XXX> = {
Test2: XXX
}
type _a = number
type _b = string
type A = Test2<_a>
type B = Test2<_b>
const TestSemigroupTest2a: Semigroup<A> = {
concat: (x, y) => ({
Test2:
x !== undefined && y !== undefined
? x.Test2 + y.Test2
: x !== undefined
? x.Test2
: y !== undefined
? y.Test2
: 0
})
}
const _compare_b = (x: B, y: B) => (x.Test2 > y.Test2 ? 1 : x.Test2 < y.Test2 ? -1 : 0)
const _concat_b = (x: B, y: B) => {
const array = [x, y].sort(_compare_b)
return `${array[0].Test2} - ${array[1].Test2}`
}
const TestSemigroupTest2b: Semigroup<B> = {
concat: (x, y) => ({
Test2:
x !== undefined && y !== undefined
? _concat_b(x, y)
: x !== undefined
? x.Test2
: y !== undefined
? y.Test2
: ''
})
}
const TestOrdTest2a: Ord<A> = {
compare: (first, second) =>
first.Test2 > second.Test2 ? 1 : first.Test2 < second.Test2 ? -1 : 0,
equals: (x, y) => x.Test2 === y.Test2
}
const TestOrdTest2b: Ord<B> = {
compare: _compare_b,
equals: (x, y) => x.Test2 === y.Test2
}
describe('fp-ts Tutorial', () => {
it('Semigroup', () => {
// base
const a1: A = { Test2: 123 }
const a2: A = { Test2: 456 }
const a3: A = { Test2: 789 }
const b1: B = { Test2: 'abc' }
const b2: B = { Test2: 'def' }
const b3: B = { Test2: 'ghi' }
// object
const record_a12: Record<string, A> = {
key1: a1,
key2: a2
}
const record_a23: Record<string, A> = {
key2: a2,
key3: a3
}
const record_b12: Record<string, B> = {
key1: b1,
key2: b2
}
const record_b23: Record<string, B> = {
key2: b2,
key3: b3
}
const record_ab12: Record<string, A | B> = {
key1: a1,
key2: b2
}
const record_ab23: Record<string, A | B> = {
key2: b2,
key3: a3
}
const tuple_a123: [A, A, A] = [a1, a2, a3]
const tuple_a231: [A, A, A] = [a2, a3, a1]
const tuple_a12: [A, A, A] = [a1, a2] as any
const tuple_a23: [A, A, A] = [a2, a3] as any
const tuple_b123: [B, B, B] = [b1, b2, b3]
const tuple_b231: [B, B, B] = [b2, b3, b1]
const tuple_b12: [B, B, B] = [b1, b2] as any
const tuple_b23: [B, B, B] = [b2, b3] as any
const tuple_ab123: [A, B, A] = [a1, b2, a3]
const tuple_ab231: [A, B, A] = [a2, b3, a1]
const tuple_ab12: [A, B, A] = [a1, b2] as any
const tuple_ab23: [A, B, A] = [a2, b3] as any
const array_a123: A[] = [a1, a2, a3]
const array_b123: B[] = [b1, b2, b3]
// function object
const record_sa123: Record<string, Semigroup<A>> = {
key1: TestSemigroupTest2a,
key2: TestSemigroupTest2a,
key3: TestSemigroupTest2a
}
const record_sb123: Record<string, Semigroup<B>> = {
key1: TestSemigroupTest2b,
key2: TestSemigroupTest2b,
key3: TestSemigroupTest2b
}
const record_sab123: Record<string, Semigroup<A | B>> = {
key1: TestSemigroupTest2a as any,
key2: TestSemigroupTest2b as any,
key3: TestSemigroupTest2a as any
}
// // check
// console.log(
// 'concat - check - a1, (a2, a3) - ',
// TestSemigroupTest2a.concat(a1, TestSemigroupTest2a.concat(a2, a3))
// )
// console.log(
// 'concat - check - (a1, a2), a3 - ',
// TestSemigroupTest2a.concat(TestSemigroupTest2a.concat(a1, a2), a3)
// )
// console.log(
// 'concat - check - b1, (b2, b3) - ',
// TestSemigroupTest2b.concat(b1, TestSemigroupTest2b.concat(b2, b3))
// )
// console.log(
// 'concat - check - (b1, b2), b3 - ',
// TestSemigroupTest2b.concat(TestSemigroupTest2b.concat(b1, b2), b3)
// )
// console.log('---------')
// test
console.log('concat (a1,a2) - (', a1, ',', a2, ') => ', TestSemigroupTest2a.concat(a1, a2))
console.log('concat (b1,b2) - (', b1, ',', b2, ') => ', TestSemigroupTest2b.concat(b1, b2))
console.log('---------')
console.log(
'min - concat (a1,a2) - (',
a1,
',',
a2,
') => ',
S.min(TestOrdTest2a).concat(a1, a2)
)
console.log(
'min - concat (b1,b2) - (',
b1,
',',
b2,
') => ',
S.min(TestOrdTest2b).concat(b1, b2)
)
console.log('---------')
console.log(
'max - concat (a1,a2) - (',
a1,
',',
a2,
') => ',
S.max(TestOrdTest2a).concat(a1, a2)
)
console.log(
'max - concat (b1,b2) - (',
b1,
',',
b2,
') => ',
S.max(TestOrdTest2b).concat(b1, b2)
)
console.log('---------')
console.log(
'constant - a1 - concat (a1,a2) - (',
a1,
',',
a2,
') => ',
S.constant(a1).concat(a1, a2)
)
console.log(
'constant - a2 - concat (a1,a2) - (',
a1,
',',
a2,
') => ',
S.constant(a2).concat(a1, a2)
)
console.log(
'constant - a3 - concat (a1,a2) - (',
a1,
',',
a2,
') => ',
S.constant(a3).concat(a1, a2)
)
console.log(
'constant - b1 - concat (b1,b2) - (',
b1,
',',
b2,
') => ',
S.constant(b1).concat(b1, b2)
)
console.log(
'constant - b2 - concat (b1,b2) - (',
b1,
',',
b2,
') => ',
S.constant(b2).concat(b1, b2)
)
console.log(
'constant - b3 - concat (b1,b2) - (',
b1,
',',
b2,
') => ',
S.constant(b3).concat(b1, b2)
)
console.log('---------')
console.log(
'reverse - concat (a1,a2) - (',
a1,
',',
a2,
') => ',
S.reverse(TestSemigroupTest2a).concat(a1, a2)
)
console.log(
'reverse - concat (b1,b2) - (',
b1,
',',
b2,
') => ',
S.reverse(TestSemigroupTest2b).concat(b1, b2)
)
console.log('---------')
console.log(
'struct - concat (record_sa123, record_a12, record_a23) - (',
record_sa123,
',',
record_a12,
',',
record_a23,
') => ',
S.struct(record_sa123).concat(record_a12, record_a23)
)
console.log(
'struct - concat (record_sa123, record_a12, record_a12) - (',
record_sa123,
',',
record_a12,
',',
record_a12,
') => ',
S.struct(record_sa123).concat(record_a12, record_a12)
)
console.log(
'struct - concat (record_sb123, record_b12, record_b23) - (',
record_sb123,
',',
record_b12,
',',
record_b23,
') => ',
S.struct(record_sb123).concat(record_b12, record_b23)
)
console.log(
'struct - concat (record_sb123, record_b12, record_b12) - (',
record_sb123,
',',
record_b12,
',',
record_b12,
') => ',
S.struct(record_sb123).concat(record_b12, record_b12)
)
console.log(
'struct - concat (record_sab123, record_ab12, record_ab23) - (',
record_sab123,
',',
record_ab12,
',',
record_ab23,
') => ',
S.struct(record_sab123).concat(record_ab12, record_ab23)
)
console.log(
'struct - concat (record_sab123, record_ab12, record_ab12) - (',
record_sab123,
',',
record_ab12,
',',
record_ab12,
') => ',
S.struct(record_sab123).concat(record_ab12, record_ab12)
)
console.log('---------')
console.log(
'tuple - concat (tuple_a123, tuple_a231) - (',
tuple_a123,
',',
tuple_a231,
') => ',
S.tuple(TestSemigroupTest2a, TestSemigroupTest2a, TestSemigroupTest2a).concat(
tuple_a123,
tuple_a231
)
)
console.log(
'tuple - concat (record_a12, record_a23) - (',
tuple_a12,
',',
tuple_a23,
') => ',
S.tuple(TestSemigroupTest2a, TestSemigroupTest2a, TestSemigroupTest2a).concat(
tuple_a12,
tuple_a23
)
)
console.log(
'tuple - concat (tuple_b123, tuple_b231) - (',
tuple_b123,
',',
tuple_b231,
') => ',
S.tuple(TestSemigroupTest2b, TestSemigroupTest2b, TestSemigroupTest2b).concat(
tuple_b123,
tuple_b231
)
)
console.log(
'tuple - concat (record_b12, record_b23) - (',
tuple_b12,
',',
tuple_b23,
') => ',
S.tuple(TestSemigroupTest2b, TestSemigroupTest2b, TestSemigroupTest2b).concat(
tuple_b12,
tuple_b23
)
)
console.log(
'tuple - concat (tuple_ab123, tuple_ab231) - (',
tuple_ab123,
',',
tuple_ab231,
') => ',
S.tuple(TestSemigroupTest2a, TestSemigroupTest2b, TestSemigroupTest2a).concat(
tuple_ab123,
tuple_ab231
)
)
console.log(
'tuple - concat (record_ab12, record_ab23) - (',
tuple_ab12,
',',
tuple_ab23,
') => ',
S.tuple(TestSemigroupTest2a, TestSemigroupTest2b, TestSemigroupTest2a).concat(
tuple_ab12,
tuple_ab23
)
)
console.log('---------')
console.log(
'intercalate - a1 - concat (a1, a2) - (',
a1,
',',
a2,
') => ',
S.intercalate(a1)(TestSemigroupTest2a).concat(a1, a2)
)
console.log(
'intercalate - a2 - concat (a1, a2) - (',
a1,
',',
a2,
') => ',
S.intercalate(a2)(TestSemigroupTest2a).concat(a1, a2)
)
console.log(
'intercalate - a3 - concat (a1, a2) - (',
a1,
',',
a2,
') => ',
S.intercalate(a3)(TestSemigroupTest2a).concat(a1, a2)
)
console.log(
'intercalate - b1 - concat (b1, b2) - (',
b1,
',',
b2,
') => ',
S.intercalate(b1)(TestSemigroupTest2b).concat(b1, b2)
)
console.log(
'intercalate - b2 - concat (b1, b2) - (',
b1,
',',
b2,
') => ',
S.intercalate(b2)(TestSemigroupTest2b).concat(b1, b2)
)
console.log(
'intercalate - b3 - concat (b1, b2) - (',
b1,
',',
b2,
') => ',
S.intercalate(b3)(TestSemigroupTest2b).concat(b1, b2)
)
console.log('---------')
console.log('first - concat (a1, a2) - (', a1, ',', a2, ') => ', S.first<A>().concat(a1, a2))
console.log('first - concat (b1, b2) - (', b1, ',', b2, ') => ', S.first<B>().concat(b1, b2))
console.log('---------')
console.log('last - concat (a1, a2) - (', a1, ',', a2, ') => ', S.last<A>().concat(a1, a2))
console.log('last - concat (b1, b2) - (', b1, ',', b2, ') => ', S.last<B>().concat(b1, b2))
console.log('---------')
console.log(
'concatAll - a1 - array_a123 - ',
array_a123,
' => ',
S.concatAll(TestSemigroupTest2a)(a1)(array_a123)
)
console.log(
'concatAll - a1 - tuple_a231 - ',
tuple_a231,
' => ',
S.concatAll(TestSemigroupTest2a)(a1)(tuple_a231)
)
console.log(
'concatAll - b1 - array_b123 - ',
array_b123,
' => ',
S.concatAll(TestSemigroupTest2b)(b1)(array_b123)
)
console.log(
'concatAll - b1 - tuple_b231 - ',
tuple_b231,
' => ',
S.concatAll(TestSemigroupTest2b)(b1)(tuple_b231)
)
})
})
実行結果
concat (a1,a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 579 }
concat (b1,b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'abc - def' }
---------
min - concat (a1,a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 123 }
min - concat (b1,b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'abc' }
---------
max - concat (a1,a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 456 }
max - concat (b1,b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'def' }
---------
constant - a1 - concat (a1,a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 123 }
constant - a2 - concat (a1,a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 456 }
constant - a3 - concat (a1,a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 789 }
constant - b1 - concat (b1,b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'abc' }
constant - b2 - concat (b1,b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'def' }
constant - b3 - concat (b1,b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'ghi' }
---------
reverse - concat (a1,a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 579 }
reverse - concat (b1,b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'abc - def' }
---------
struct - concat (record_sa123, record_a12, record_a23) - ( {
key1: { concat: [Function: concat] },
key2: { concat: [Function: concat] },
key3: { concat: [Function: concat] }
} , { key1: { Test2: 123 }, key2: { Test2: 456 } } , { key2: { Test2: 456 }, key3: { Test2: 789 } } ) => { key1: { Test2: 123 }, key2: { Test2: 912 }, key3: { Test2: 789 } }
struct - concat (record_sa123, record_a12, record_a12) - ( {
key1: { concat: [Function: concat] },
key2: { concat: [Function: concat] },
key3: { concat: [Function: concat] }
} , { key1: { Test2: 123 }, key2: { Test2: 456 } } , { key1: { Test2: 123 }, key2: { Test2: 456 } } ) => { key1: { Test2: 246 }, key2: { Test2: 912 }, key3: { Test2: 0 } }
struct - concat (record_sb123, record_b12, record_b23) - ( {
key1: { concat: [Function: concat] },
key2: { concat: [Function: concat] },
key3: { concat: [Function: concat] }
} , { key1: { Test2: 'abc' }, key2: { Test2: 'def' } } , { key2: { Test2: 'def' }, key3: { Test2: 'ghi' } } ) => {
key1: { Test2: 'abc' },
key2: { Test2: 'def - def' },
key3: { Test2: 'ghi' }
}
struct - concat (record_sb123, record_b12, record_b12) - ( {
key1: { concat: [Function: concat] },
key2: { concat: [Function: concat] },
key3: { concat: [Function: concat] }
} , { key1: { Test2: 'abc' }, key2: { Test2: 'def' } } , { key1: { Test2: 'abc' }, key2: { Test2: 'def' } } ) => {
key1: { Test2: 'abc - abc' },
key2: { Test2: 'def - def' },
key3: { Test2: '' }
}
struct - concat (record_sab123, record_ab12, record_ab23) - ( {
key1: { concat: [Function: concat] },
key2: { concat: [Function: concat] },
key3: { concat: [Function: concat] }
} , { key1: { Test2: 123 }, key2: { Test2: 'def' } } , { key2: { Test2: 'def' }, key3: { Test2: 789 } } ) => {
key1: { Test2: 123 },
key2: { Test2: 'def - def' },
key3: { Test2: 789 }
}
struct - concat (record_sab123, record_ab12, record_ab12) - ( {
key1: { concat: [Function: concat] },
key2: { concat: [Function: concat] },
key3: { concat: [Function: concat] }
} , { key1: { Test2: 123 }, key2: { Test2: 'def' } } , { key1: { Test2: 123 }, key2: { Test2: 'def' } } ) => {
key1: { Test2: 246 },
key2: { Test2: 'def - def' },
key3: { Test2: 0 }
}
---------
tuple - concat (tuple_a123, tuple_a231) - ( [ { Test2: 123 }, { Test2: 456 }, { Test2: 789 } ] , [ { Test2: 456 }, { Test2: 789 }, { Test2: 123 } ] ) => [ { Test2: 579 }, { Test2: 1245 }, { Test2: 912 } ]
tuple - concat (record_a12, record_a23) - ( [ { Test2: 123 }, { Test2: 456 } ] , [ { Test2: 456 }, { Test2: 789 } ] ) => [ { Test2: 579 }, { Test2: 1245 }, { Test2: 0 } ]
tuple - concat (tuple_b123, tuple_b231) - ( [ { Test2: 'abc' }, { Test2: 'def' }, { Test2: 'ghi' } ] , [ { Test2: 'def' }, { Test2: 'ghi' }, { Test2: 'abc' } ] ) => [
{ Test2: 'abc - def' },
{ Test2: 'def - ghi' },
{ Test2: 'abc - ghi' }
]
tuple - concat (record_b12, record_b23) - ( [ { Test2: 'abc' }, { Test2: 'def' } ] , [ { Test2: 'def' }, { Test2: 'ghi' } ] ) => [ { Test2: 'abc - def' }, { Test2: 'def - ghi' }, { Test2: '' } ]
tuple - concat (tuple_ab123, tuple_ab231) - ( [ { Test2: 123 }, { Test2: 'def' }, { Test2: 789 } ] , [ { Test2: 456 }, { Test2: 'ghi' }, { Test2: 123 } ] ) => [ { Test2: 579 }, { Test2: 'def - ghi' }, { Test2: 912 } ]
tuple - concat (record_ab12, record_ab23) - ( [ { Test2: 123 }, { Test2: 'def' } ] , [ { Test2: 456 }, { Test2: 'ghi' } ] ) => [ { Test2: 579 }, { Test2: 'def - ghi' }, { Test2: 0 } ]
---------
intercalate - a1 - concat (a1, a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 702 }
intercalate - a2 - concat (a1, a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 1035 }
intercalate - a3 - concat (a1, a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 1368 }
intercalate - b1 - concat (b1, b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'abc - abc - def' }
intercalate - b2 - concat (b1, b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'abc - def - def' }
intercalate - b3 - concat (b1, b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'abc - def - ghi' }
---------
first - concat (a1, a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 123 }
first - concat (b1, b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'abc' }
---------
last - concat (a1, a2) - ( { Test2: 123 } , { Test2: 456 } ) => { Test2: 456 }
last - concat (b1, b2) - ( { Test2: 'abc' } , { Test2: 'def' } ) => { Test2: 'def' }
---------
concatAll - a1 - array_a123 - [ { Test2: 123 }, { Test2: 456 }, { Test2: 789 } ] => { Test2: 1491 }
concatAll - a1 - tuple_a231 - [ { Test2: 456 }, { Test2: 789 }, { Test2: 123 } ] => { Test2: 1491 }
concatAll - b1 - array_b123 - [ { Test2: 'abc' }, { Test2: 'def' }, { Test2: 'ghi' } ] => { Test2: 'abc - abc - def - ghi' }
concatAll - b1 - tuple_b231 - [ { Test2: 'def' }, { Test2: 'ghi' }, { Test2: 'abc' } ] => { Test2: 'abc - abc - def - ghi' }