import * as EQUAL from "@effect-ts/core/Equal"
import type { Equal } from "@effect-ts/core/Equal"
import * as ORD from "@effect-ts/core/Ord"
import type { Ord } from "@effect-ts/core/Ord"
import * as CNK from "@fp-ts/data/Chunk"
/**
* @tsplus getter ets/Ord toOrder
*/
export function convertOrd(_: Ord): Order {
return ({ compare: x => y => _.compare(x, y) })
}
/**
* @tsplus pipeable fp-ts/data/Chunk sortWith
*/
export function sortWith(
...ords: NonEmptyArguments>
): (a: Chunk) => Chunk {
// TODO
return as => as.toArray.sortWith(...ords).toChunk
}
/**
* @tsplus getter Generator toArray
*/
export function toArray(
gen: Generator
) {
return Array.from(gen)
}
/**
* Remove duplicates from an array, keeping the first occurrence of an element.
*
* @tsplus static ReadonlyArray.Ops uniq
* @tsplus pipeable ReadonlyArray uniq
*/
export function uniqArray(E: Equal) {
return (self: ReadonlyArray): ReadonlyArray => {
const includes = arrayIncludes(E)
const result: Array = []
const length = self.length
let i = 0
for (; i < length; i = i + 1) {
const a = self[i]!
if (!includes(result, a)) {
result.push(a)
}
}
return length === result.length ? self : result
}
}
function arrayIncludes(E: Equal) {
return (array: Array, value: A): boolean => {
for (let i = 0; i < array.length; i = i + 1) {
const element = array[i]!
if (E.equals(value, element)) {
return true
}
}
return false
}
}
/**
* Remove duplicates from an array, keeping the first occurrence of an element.
*
* @tsplus static fp-ts/data/Chunk.Ops uniq
* @tsplus pipeable fp-ts/data/Chunk uniq
*/
export function uniq(E: Equal) {
return (self: Chunk): Chunk => {
let out = ([] as A[]).toChunk
for (let i = 0; i < self.length; i++) {
const a = self.unsafeGet(i)
if (!out.elem2(E, a)) {
out = out.append(a)
}
}
return self.length === out.length ? self : out
}
}
/**
* Test if a value is a member of an array. Takes a `Equivalence` as a single
* argument which returns the function to use to search for a value of type `A`
* in an array of type `Chunk`.
*
* @tsplus static fp-ts/data/Chunk.Ops elem2
* @tsplus pipeable fp-ts/data/Chunk elem2
*/
export function elem(E: Equal, value: A) {
return (self: Chunk): boolean => {
const predicate = (element: A) => E.equals(element, value)
for (let i = 0; i < self.length; i++) {
if (predicate(self.unsafeGet(i)!)) {
return true
}
}
return false
}
}
/**
* @tsplus pipeable ReadonlyArray sortWithNonEmpty
*/
export function sortWithNonEmpty(
...ords: NonEmptyArguments>
): (a: NonEmptyReadonlyArray) => NonEmptyArray {
return a => a.sortByNonEmpty(...ords.map(convertOrd))
}
/**
* @tsplus pipeable fp-ts/data/Chunk partition
*/
export const ChunkPartition = CNK.partition
/**
* @tsplus fluent ets/Equal contramap
*/
export function EqlContramap(fa: Equal, f: (a: B) => A) {
return EQUAL.contramap(f)(fa)
}
/**
* @tsplus fluent ets/Ord contramap
*/
export const OrdContramap = ORD.contramap_
/**
* @tsplus getter ets/Ord inverted
*/
export const OrdInverted = ORD.inverted