fp-ts-graph
Immutable, functional graph data structure for fp-ts.
type Graph<Id, Edge, Node> = ...
Quality | y/n |
---|
directed | yes |
cyclic | yes |
multiple edges | no |
In the future a granular distinction of graph qualities may be supported, see roadmap.
Table of Contents
What it is
What it's not
A rendering engine or anything that has to do with a visual representation of a graph. However, for for debugging purpose we provide simple graphviz dotfile generator.
Install
npm install fp-ts @no-day/fp-ts-graph
Docs
API Docs
Examples
Define Types
import { Graph } from '@no-day/fp-ts-graph';
export type MyId = number;
export type MyNode = { firstName: string; lastName: string; age: number };
export type MyEdge = { items: number[] };
export type MyGraph = Graph<MyId, MyEdge, MyNode>;
Build Graph
import Graph, * as graph from '@no-day/fp-ts-graph';
import * as fp from 'fp-ts';
import { MyEdge, MyId, MyNode, MyGraph } from './types';
const empty = graph.empty<MyId, MyEdge, MyNode>();
const insertNode = graph.insertNode(fp.eq.eqNumber);
const insertEdge = graph.insertEdge(fp.eq.eqNumber);
export const myGraph: fp.option.Option<MyGraph> = fp.function.pipe(
empty,
insertNode(1001, {
firstName: 'Tonicha',
lastName: 'Crowther',
age: 45,
}),
insertNode(1002, {
firstName: 'Samual',
lastName: 'Sierra',
age: 29,
}),
insertNode(1003, {
firstName: 'Khushi',
lastName: 'Walter',
age: 40,
}),
insertNode(1004, {
firstName: 'Rian',
lastName: 'Ruiz',
age: 56,
}),
fp.option.of,
fp.option.chain(insertEdge(1001, 1002, { items: [2, 3] })),
fp.option.chain(insertEdge(1002, 1003, { items: [4] })),
fp.option.chain(insertEdge(1001, 1003, { items: [9, 4, 3] })),
fp.option.chain(insertEdge(1003, 1004, { items: [2, 3] }))
);
Debug graph visually
import * as graph from '@no-day/fp-ts-graph';
import * as fp from 'fp-ts';
import { myGraph } from './build-graph';
fp.function.pipe(
myGraph,
fp.option.map(
fp.function.flow(
graph.mapEdges(({ items }) => items.join(', ')),
graph.map(
({ firstName, lastName, age }) => `${lastName}, ${firstName} (${age})`
),
graph.toDotFile((_) => _.toString())
)
),
fp.option.fold(
() => console.error('invalid graph!'),
console.log
)
);
If you have graphviz installed you can run the following in the terminal:
ts-node examples/debug-visually.ts | dot -Tsvg > graph.svg
chromium graph.svg
Roadmap / to do
- Add instances
- Add functions
deleteNode
deleteEdge
outgoingIds
incomingIds
mapEdgeWithIndex
mapWithIndex
topologicalSort
- ...
- Ideas
- Represent different qualities of a graph on the type level
Like: Graph<{directed: true, multiEdge: true, cyclic: false}, Id, Edge, Node>