gcanti / fp-ts

Functional programming in TypeScript
https://gcanti.github.io/fp-ts/
MIT License
10.73k stars 504 forks source link

Array.chunksOf could return Array<NonEmptyArray<A>> #1407

Closed anthonyjoeseph closed 3 years ago

anthonyjoeseph commented 3 years ago

🐛 Bug report

Array.chunksOf could return Array<NonEmptyArray>

Current Behavior

export function chunksOf(n: number): <A>(as: ReadonlyArray<A>) => ReadonlyArray<ReadonlyArray<A>> {
  const f = chop(splitAt(n))
  return (as) => (as.length === 0 ? empty : isOutOfBound(n - 1, as) ? [as] : f(as))
}

current 3.0.0

Expected behavior

const chunksOf: (n: number) => <A>(as: ReadonlyArray<A>) => ReadonlyArray<ReadonlyNonEmptyArray<A>>

Reproducible example

Suggested solution(s)

import * as RNEA from './ReadonlyNonEmptyArray'

export function chunksOf(n: number): <A>(as: ReadonlyArray<A>) => ReadonlyArray<RNEA.ReadonlyNonEmptyArray<A>> {
  return n >= 1
    ? flow(chop(flow(splitAt(n), ([a, b]) => [RNEA.fromReadonlyArray(a), b])), compact)
    : flow(
        RNEA.fromReadonlyArray,
        O.fold(() => empty, of)
      )
}

Additional context

Not sure if this is more correct, but seems doable.

I'm willing to make PRs for this if this is desired

Your environment

Which versions of fp-ts are affected by this issue? Did this work in previous versions of fp-ts?

Software Version(s)
fp-ts 1.10.0 -> current
TypeScript N/A
gcanti commented 3 years ago

Thank you @anthonyjoeseph, just finished a big refactoring (PR) involving the ReadonlyArray and ReadonlyNonEmptyArray which should allow us to improve the chunksOf signature. WDYT?

anthonyjoeseph commented 3 years ago

Wow this is huge! It looks great. I much prefer your approach of implementing chop & splitAt & chunksOf in ReadonlyNonEmptyArray, and using that to implement everything else