fp-ts Semigroupの内容確認

fp-tsの一覧ページがあまりにも重くなったので、分割

# 参照元

https://gcanti.github.io/fp-ts/modules/

## 一覧

https://qiita.com/kuangzhixitian3/items/3fc5d8abd6fe170d7489

### Semigroupの内容確認 

参考

https://github.com/gcanti/fp-ts/blob/master/docs/modules/Semigroup.ts.md

<table>
  <thead>
    <tr>
      <th>ファイル名</th> 
      <th>import先</th> 
      <th>ソースの中身</th>
      <th>declare module がある</th>
      <th>importでの参照される数</th>
    </tr>
  </thead>

  <tr>
    <td>Semigroup</td> 
    <td>
        <ul>
            <li>function</li>
            <li>internal</li>
            <li>Magma</li>
            <li>Ord</li>
            <li>ReadonlyRecord</li>
        </ul>
    </td>
    <td>interface, function, const のみ</td>
    <td>なし</td>
    <td>13</td>
  </tr>
  
</table>

https://ja.wikipedia.org/wiki/%E5%8D%8A%E7%BE%A4

満たすべきもの

結合律

```math
(a \cdot b) \cdot c = a \cdot (b \cdot c)
```

```ts
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)
    )
  })
})
```

実行結果
```ts
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を作成できてしまう

```ts
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)
    )
  })
})
```

```ts
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の利用 

```ts
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)
    )
  })
})
```

実行結果
```ts
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' }
```