https://github.com/aenario/circularmemo
Memoization function with support for circular references.
https://github.com/aenario/circularmemo
Last synced: 5 months ago
JSON representation
Memoization function with support for circular references.
- Host: GitHub
- URL: https://github.com/aenario/circularmemo
- Owner: aenario
- Created: 2020-05-01T18:10:36.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2022-12-30T20:19:28.000Z (over 3 years ago)
- Last Synced: 2025-11-23T22:06:38.068Z (8 months ago)
- Language: TypeScript
- Size: 75.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# circularmemo
A convenience function to recursively iterates over a (like typescript's types)
with memoization and without breaking circular references.
It requires your function to expect itself as the first argument, and returns
a similar function, you can then pass your function to a Y-combinator to get a
"normal" function.
This package also provides a spreading Y combinator and the `MFN` type for this kind of
self-passed function.
```typescript
import { Y, circularmemo, MFN } from 'circularmemo'
interface Node {
n: number,
left: Node,
}
const circle: Node = { n: 1, left: { n: 2, left: (null as unknown as Node) } }
circle.left.left = circle
const _plusX: MFN<[Node, number], Node> = (self, x, n) =>
({ n: x.n + n, left: self(x.left, n) })
const plusX = Y(circularmemo({
circularMarker: (_) => ({} as Node), // leave an empty object, which will be
replaceMarker: (marker, res) => Object.assign(marker, res) // fill up the object
}, _plusX))
const result = plusX(circle, 1)
assert(result.n === 2)
assert(result.left.n === 3)
assert(result.left.left === result) // maintained circular
```
## Other options
The first arguments to `circularmemo` is a Param object which accepts
the following functions.
```typescript
circularMarker: (...args: Args) => Marker,
replaceMarker: (tmp: Marker, final: Res) => Res
useMarker?: (tmp: Marker) => Res,
useExisting?: (existing: Res) => Res,
shouldMemo?: (...args: Args) => boolean,
keyMaker?: (...args: Args) => Key,
```