Skip to content

Commit

Permalink
feat!: Remake Lens as Optical (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikuroXina authored Aug 31, 2023
1 parent 06fa9b6 commit 7d6a466
Show file tree
Hide file tree
Showing 32 changed files with 1,063 additions and 626 deletions.
32 changes: 2 additions & 30 deletions src/cofree.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ComonadCofree } from "./cofree/comonad.js";
import { compose, pipe } from "./func.js";
import { compose } from "./func.js";
import type { Apply2Only, Get1, Hkt2 } from "./hkt.js";
import {
defer as lazyDefer,
Expand All @@ -11,9 +11,8 @@ import {
partialEq as lazyPartialEq,
partialOrd as lazyPartialOrd,
} from "./lazy.js";
import { mapOr, type Option } from "./option.js";
import { type Option } from "./option.js";
import type { Ordering } from "./ordering.js";
import { appendToHead, empty, type Seq, viewL } from "./seq.js";
import {
eq as tupleEq,
map as tupleMap,
Expand All @@ -29,7 +28,6 @@ import { kleisli, liftM, type Monad } from "./type-class/monad.js";
import { fromCmp, type Ord } from "./type-class/ord.js";
import { fromPartialEquality, type PartialEq } from "./type-class/partial-eq.js";
import { fromPartialCmp, type PartialOrd } from "./type-class/partial-ord.js";
import type { Representable } from "./type-class/representable.js";
import { mapM as mapMTraversable, type Traversable } from "./type-class/traversable.js";

export interface CofreeHkt extends Hkt2 {
Expand Down Expand Up @@ -314,29 +312,3 @@ export const comonadCofree = <F>(f: Functor<F>): ComonadCofree<F, Apply2Only<Cof
functor: f,
unwrap,
});

/**
* The instance of `Representable` for `Cofree<F, _>`, requires the `Representable` for `F`.
*
* @param rep - The instance of `Representable` for `F`.
* @returns The instance of `Representable` for `Cofree<F, _>`.
*/
export const representable = <F, Rep>(
rep: Representable<F, Rep>,
): Representable<Apply2Only<CofreeHkt, F>, Seq<Rep>> => {
const index =
<A>(cofree: Cofree<F, A>) =>
(key: Seq<Rep>): A => {
const [a, as] = force(cofree);
return mapOr(a)(([k, ks]: Tuple<Rep, Seq<Rep>>) => index(rep.index(as)(k))(ks))(
viewL(key),
);
};
const tabulate = <A>(f: (key: Seq<Rep>) => A): Cofree<F, A> =>
make(f(empty))(rep.tabulate((k) => tabulate(pipe(appendToHead(k))(f))));
return {
map: map(rep),
index,
tabulate,
};
};
4 changes: 2 additions & 2 deletions src/curry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { type FnHkt, representable as representableFn } from "./func.js";
import type { Apply2Only } from "./hkt.js";
import { functor as functorTuple, type TupleHkt } from "./tuple.js";
import type { Adjunction } from "./type-class/adjunction.js";
import type { ApplyRep } from "./type-class/representable.js";

type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
? true
Expand Down Expand Up @@ -45,8 +46,7 @@ export function curry<F extends (...args: unknown[]) => unknown>(fn: F): Curried
*/
export const curryAdjunction = <E>(): Adjunction<
Apply2Only<TupleHkt, E>,
Apply2Only<FnHkt, E>,
E
ApplyRep<Apply2Only<FnHkt, E>, E>
> => ({
functor: functorTuple(),
representable: representableFn<E>(),
Expand Down
41 changes: 0 additions & 41 deletions src/free.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
import { type Cofree, type CofreeHkt, extract, make, representable, unwrap } from "./cofree.js";
import { pipe } from "./func.js";
import type { Apply2Only, Get1, Hkt2 } from "./hkt.js";
import * as Option from "./option.js";
import { greater, less, type Ordering } from "./ordering.js";
import * as Result from "./result.js";
import type { Seq } from "./seq.js";
import type { Tuple } from "./tuple.js";
import {
type Adjunction,
extractL,
indexAdjunction,
leftAdjunct,
rightAdjunct,
tabulateAdjunction,
unsplitL,
} from "./type-class/adjunction.js";
import type { Applicative } from "./type-class/applicative.js";
import { type Eq, fromEquality } from "./type-class/eq.js";
import type { Functor } from "./type-class/functor.js";
Expand Down Expand Up @@ -425,32 +413,3 @@ export const monad = <F>(f: Functor<F>): Monad<Apply2Only<FreeHkt, F>> => ({
flatMap: flatMapT(f),
apply: applyT(f),
});

/**
* The instance of `Adjunction` for `Free<F, _>` against to `Cofree<U, _>`.
*/
export const adjunction = <F, U, Rep>(
adj: Adjunction<F, U, Rep>,
): Adjunction<Apply2Only<FreeHkt, F>, Apply2Only<CofreeHkt, U>, Seq<Rep>> => ({
functor: functor(adj.functor),
representable: representable(adj.representable),
unit: <A>(a: A) =>
make(pure(a))(
tabulateAdjunction(adj)((k) =>
leftAdjunct(adjunction(adj))(
pipe((x) => unsplitL(adj.functor)(x)(k))(
node as (f: Get1<F, Free<F, A>>) => Free<F, A>,
),
)(a),
),
),
counit: <A>(free: Free<F, Cofree<U, A>>): A => {
if (isPure(free)) {
return extract(free[1]);
}
const extracted = extractL(adj)(free[1]);
return rightAdjunct(adjunction(adj))<Cofree<U, A>, A>(
(cofree: Cofree<U, A>): Cofree<U, A> => indexAdjunction(adj)(unwrap(cofree))(free[1]),
)(extracted);
},
});
10 changes: 0 additions & 10 deletions src/func.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import type { Arrow } from "./type-class/arrow.js";
import type { Functor } from "./type-class/functor.js";
import { type Group } from "./type-class/group.js";
import type { Monad } from "./type-class/monad.js";
import type { Representable } from "./type-class/representable.js";
import { semiGroupSymbol } from "./type-class/semi-group.js";

/**
Expand Down Expand Up @@ -188,15 +187,6 @@ export const monadReader = <R>(): MonadReader<R, Apply2Only<FnHkt, R>> => ({
local: pipe,
});

/**
* The instance of `Representable` for `Fn<E, _>`.
*/
export const representable = <E>(): Representable<Apply2Only<FnHkt, E>, E> => ({
map: compose,
index: id,
tabulate: id,
});

/**
* The instance of `Arrow` for `Fn`. It is useful to construct the bifunctor with functions.
*/
Expand Down
22 changes: 22 additions & 0 deletions src/hkt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ export interface Hkt3 extends Hkt2 {
export interface Hkt4 extends Hkt3 {
readonly arg4: unknown;
}
/**
* Type of order 5. `arg5 -> arg4 -> arg3 -> arg2 -> arg1 -> *`.
*/
export interface Hkt5 extends Hkt4 {
readonly arg5: unknown;
}

/**
* Applies the first type parameter to HKT.
Expand Down Expand Up @@ -73,6 +79,18 @@ export type Apply4Only<S, A4> = S extends Hkt4
* Applies the first, second, third and fourth type parameter to HKT.
*/
export type Apply4<S, A1, A2, A3, A4> = Apply3<S, A1, A2, A3> & Apply4Only<S, A4>;
/**
* Applies the fifth type parameter to HKT.
*/
export type Apply5Only<S, A5> = S extends Hkt5
? S & {
readonly arg4: A5;
}
: never;
/**
* Applies the first, second, third, fourth and fifth type parameter to HKT.
*/
export type Apply5<S, A1, A2, A3, A4, A5> = Apply4<S, A1, A2, A3, A4> & Apply5Only<S, A5>;

/**
* Gets the applied type of HKT.
Expand All @@ -95,3 +113,7 @@ export type Get3<S, A3, A2, A1> = Instance<Apply3<S, A1, A2, A3>>;
* Applies four type parameters and gets the applied type of HKT.
*/
export type Get4<S, A4, A3, A2, A1> = Instance<Apply4<S, A1, A2, A3, A4>>;
/**
* Applies five type parameters and gets the applied type of HKT.
*/
export type Get5<S, A5, A4, A3, A2, A1> = Instance<Apply5<S, A1, A2, A3, A4, A5>>;
23 changes: 1 addition & 22 deletions src/identity.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { constant, flip, id } from "./func.js";
import { flip, id } from "./func.js";
import type { Hkt1 } from "./hkt.js";
import type { Adjunction } from "./type-class/adjunction.js";
import type { Comonad } from "./type-class/comonad.js";
import type { Distributive } from "./type-class/distributive.js";
import type { Functor } from "./type-class/functor.js";
import type { Monad } from "./type-class/monad.js";
import type { Representable } from "./type-class/representable.js";
import type { Settable } from "./type-class/settable.js";
import type { Traversable } from "./type-class/traversable.js";

Expand Down Expand Up @@ -77,22 +75,3 @@ export const settable: Settable<IdentityHkt> = {
...distributive,
untainted: id,
};

/**
* The instance of `Representable` for `Identity` with `[]` representation.
*/
export const representable: Representable<IdentityHkt, []> = {
...functor,
index: constant,
tabulate: (f) => f([]),
};

/**
* The instance of `Adjunction` for `Identity` against to itself with `[]` representation..
*/
export const adjunction: Adjunction<IdentityHkt, IdentityHkt, []> = {
functor,
representable,
unit: id,
counit: id,
};
Loading

0 comments on commit 7d6a466

Please sign in to comment.