/** * @since 0.24.0 */ import type { Kind, TypeLambda } from "effect/HKT" import type { Of } from "./Of.js" import type { SemiProduct } from "./SemiProduct.js" /** * @category type class * @since 0.24.0 */ export interface Product extends SemiProduct, Of { readonly productAll: ( collection: Iterable> ) => Kind> } /** * @since 0.24.0 */ export const tuple = (F: Product) => >>(...elements: T): Kind< F, ([T[number]] extends [Kind] ? R : never), (T[number] extends never ? never : [T[number]] extends [Kind] ? O : never), (T[number] extends never ? never : [T[number]] extends [Kind] ? E : never), { [I in keyof T]: [T[I]] extends [Kind] ? A : never } > => F.productAll(elements) as any /** * @since 0.24.0 */ export const struct = (F: Product) => }>(fields: R): Kind< F, ([R[keyof R]] extends [Kind] ? R : never), (R[keyof R] extends never ? never : [R[keyof R]] extends [Kind] ? O : never), (R[keyof R] extends never ? never : [R[keyof R]] extends [Kind] ? E : never), { [K in keyof R]: [R[K]] extends [Kind] ? A : never } > => { const keys = Object.keys(fields) return F.imap(F.productAll(keys.map((k) => fields[k])), (values) => { const out: any = {} for (let i = 0; i < values.length; i++) { out[keys[i]] = values[i] } return out }, (r) => keys.map((k) => r[k])) }