(config?: TopoConfig): <N, E, T extends Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>
) => NodeWalker<N>
<N, E, T extends Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>,
config?: TopoConfig
): NodeWalker<N>Creates a new topological sort iterator with optional configuration.
Details
The iterator uses Kahn's algorithm to lazily produce nodes in topological order. Throws an error if the graph contains cycles.
Example (Sorting topologically)
import { Graph } from "effect"
const graph = Graph.directed<string, number>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
const c = Graph.addNode(mutable, "C")
Graph.addEdge(mutable, a, b, 1)
Graph.addEdge(mutable, b, c, 1)
})
// Standard topological sort
const topo1 = Graph.topo(graph)
for (const nodeIndex of Graph.indices(topo1)) {
console.log(nodeIndex) // 0, 1, 2 (topological order)
}
// With initial nodes
const topo2 = Graph.topo(graph, { initials: [0] })
// Check before sorting a cyclic graph
const cyclicGraph = Graph.directed<string, number>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
Graph.addEdge(mutable, a, b, 1)
Graph.addEdge(mutable, b, a, 2) // Creates cycle
})
if (!Graph.isAcyclic(cyclicGraph)) {
console.log("cyclic graph") // cyclic graph
}export const const topo: {
(config?: TopoConfig): <
N,
E,
T extends Kind = "directed"
>(
graph: Graph<N, E, T> | MutableGraph<N, E, T>
) => NodeWalker<N>
<N, E, T extends Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>,
config?: TopoConfig
): NodeWalker<N>
}
Creates a new topological sort iterator with optional configuration.
Details
The iterator uses Kahn's algorithm to lazily produce nodes in topological order.
Throws an error if the graph contains cycles.
Example (Sorting topologically)
import { Graph } from "effect"
const graph = Graph.directed<string, number>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
const c = Graph.addNode(mutable, "C")
Graph.addEdge(mutable, a, b, 1)
Graph.addEdge(mutable, b, c, 1)
})
// Standard topological sort
const topo1 = Graph.topo(graph)
for (const nodeIndex of Graph.indices(topo1)) {
console.log(nodeIndex) // 0, 1, 2 (topological order)
}
// With initial nodes
const topo2 = Graph.topo(graph, { initials: [0] })
// Check before sorting a cyclic graph
const cyclicGraph = Graph.directed<string, number>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
Graph.addEdge(mutable, a, b, 1)
Graph.addEdge(mutable, b, a, 2) // Creates cycle
})
if (!Graph.isAcyclic(cyclicGraph)) {
console.log("cyclic graph") // cyclic graph
}
topo: {
(
config: TopoConfigconfig?: TopoConfig
): <function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): NodeWalker<N>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): NodeWalker<N>T extends type Kind = "directed" | "undirected"Graph type for distinguishing directed and undirected graphs.
When to use
Use when writing graph-polymorphic types or helpers that need to preserve
whether a graph is directed or undirected.
Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>graph: interface Graph<out N, out E, T extends Kind = "directed">Immutable graph interface.
When to use
Use as the immutable graph model for code that queries, traverses,
transforms, or analyzes graph structure without mutating it.
Graph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): NodeWalker<N>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): NodeWalker<N>T> | interface MutableGraph<out N, out E, T extends Kind = "directed">Mutable graph interface.
When to use
Use when adding, removing, or updating nodes and edges inside a graph
mutation scope.
MutableGraph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): NodeWalker<N>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): NodeWalker<N>T>) => type NodeWalker<N> = Walker<number, N>Type alias for node iteration using Walker.
NodeWalker is represented as Walker<NodeIndex, N>.
When to use
Use as the shared node walker type returned by graph traversal and node
listing APIs.
NodeWalker<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): NodeWalker<N>N>
<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>T extends type Kind = "directed" | "undirected"Graph type for distinguishing directed and undirected graphs.
When to use
Use when writing graph-polymorphic types or helpers that need to preserve
whether a graph is directed or undirected.
Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>graph: interface Graph<out N, out E, T extends Kind = "directed">Immutable graph interface.
When to use
Use as the immutable graph model for code that queries, traverses,
transforms, or analyzes graph structure without mutating it.
Graph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>T> | interface MutableGraph<out N, out E, T extends Kind = "directed">Mutable graph interface.
When to use
Use when adding, removing, or updating nodes and edges inside a graph
mutation scope.
MutableGraph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>T>, config: TopoConfigconfig?: TopoConfig): type NodeWalker<N> = Walker<number, N>Type alias for node iteration using Walker.
NodeWalker is represented as Walker<NodeIndex, N>.
When to use
Use as the shared node walker type returned by graph traversal and node
listing APIs.
NodeWalker<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>N>
} = import dualdual((args: anyargs) => const isGraph: (
u: unknown
) => u is Graph<unknown, unknown>
Returns true if a value has the graph runtime type identifier, narrowing
it to a Graph.
When to use
Use to narrow an unknown value before treating it as a graph value.
Gotchas
This guard checks the shared graph runtime type identifier and does not
distinguish immutable graphs from mutable graphs.
isGraph(args: anyargs[0]), <function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>T extends type Kind = "directed" | "undirected"Graph type for distinguishing directed and undirected graphs.
When to use
Use when writing graph-polymorphic types or helpers that need to preserve
whether a graph is directed or undirected.
Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>graph: interface Graph<out N, out E, T extends Kind = "directed">Immutable graph interface.
When to use
Use as the immutable graph model for code that queries, traverses,
transforms, or analyzes graph structure without mutating it.
Graph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>T> | interface MutableGraph<out N, out E, T extends Kind = "directed">Mutable graph interface.
When to use
Use when adding, removing, or updating nodes and edges inside a graph
mutation scope.
MutableGraph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>T>,
config: TopoConfig(parameter) config: {
initials: Array<NodeIndex>;
}
config: TopoConfig = {}
): type NodeWalker<N> = Walker<number, N>Type alias for node iteration using Walker.
NodeWalker is represented as Walker<NodeIndex, N>.
When to use
Use as the shared node walker type returned by graph traversal and node
listing APIs.
NodeWalker<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>N> => {
if (graph: Graph<N, E, T> | MutableGraph<N, E, T>graph.type: T extends Kind = "directed"type === "undirected") {
throw new constructor GraphError(): GraphErrorError thrown by graph operations when the requested graph structure is
invalid, such as referencing a missing node or using unsupported edge
weights.
When to use
Use when handling failures thrown by graph operations that reject invalid
graph structure or unsupported algorithm inputs.
GraphError({ message: stringmessage: "Cannot perform topological sort on undirected graph" })
}
// Check if graph is acyclic first
if (!const isAcyclic: <
N,
E,
T extends Kind = "directed"
>(
graph: Graph<N, E, T> | MutableGraph<N, E, T>
) => boolean
Checks whether the graph is acyclic (contains no cycles).
Details
Uses depth-first search to detect back edges, which indicate cycles.
For directed graphs, any back edge creates a cycle. For undirected graphs,
a back edge that doesn't go to the immediate parent creates a cycle.
Example (Checking cycles)
import { Graph } from "effect"
// Acyclic directed graph (DAG)
const dag = Graph.directed<string, string>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
const c = Graph.addNode(mutable, "C")
Graph.addEdge(mutable, a, b, "A->B")
Graph.addEdge(mutable, b, c, "B->C")
})
console.log(Graph.isAcyclic(dag)) // true
// Cyclic directed graph
const cyclic = Graph.directed<string, string>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
Graph.addEdge(mutable, a, b, "A->B")
Graph.addEdge(mutable, b, a, "B->A") // Creates cycle
})
console.log(Graph.isAcyclic(cyclic)) // false
isAcyclic(graph: Graph<N, E, T> | MutableGraph<N, E, T>graph)) {
throw new constructor GraphError(): GraphErrorError thrown by graph operations when the requested graph structure is
invalid, such as referencing a missing node or using unsupported edge
weights.
When to use
Use when handling failures thrown by graph operations that reject invalid
graph structure or unsupported algorithm inputs.
GraphError({ message: stringmessage: "Cannot perform topological sort on cyclic graph" })
}
const const initials: number[]initials = config: TopoConfig(parameter) config: {
initials: Array<NodeIndex>;
}
config.TopoConfig.initials?: Array<NodeIndex>initials ?? []
// Validate that all initial nodes exist
for (const const nodeIndex: numbernodeIndex of const initials: number[]initials) {
if (!const hasNode: {
(nodeIndex: NodeIndex): <
N,
E,
T extends Kind = "directed"
>(
graph: Graph<N, E, T> | MutableGraph<N, E, T>
) => boolean
<N, E, T extends Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>,
nodeIndex: NodeIndex
): boolean
}
hasNode(graph: Graph<N, E, T> | MutableGraph<N, E, T>graph, const nodeIndex: numbernodeIndex)) {
throw const missingNode: (
node: number
) => GraphError
missingNode(const nodeIndex: numbernodeIndex)
}
}
return new constructor Walker<number, N>(visit: <U>(f: (index: number, data: N) => U) => Iterable<U>): Walker<number, N>Represents an iterable wrapper used by graph traversal and listing APIs.
Details
A Walker yields [index, data] pairs lazily and can be viewed as just the
indices, just the values, or mapped entries with indices, values,
entries, and visit.
Example (Working with node walkers)
import { Graph } from "effect"
const graph = Graph.directed<string, number>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
Graph.addEdge(mutable, a, b, 1)
})
// Both traversal and element iterators return NodeWalker
const dfsNodes: Graph.NodeWalker<string> = Graph.dfs(graph, { start: [0] })
const allNodes: Graph.NodeWalker<string> = Graph.nodes(graph)
// Common interface for working with node iterables
function processNodes<N>(nodeIterable: Graph.NodeWalker<N>): Array<number> {
return Array.from(Graph.indices(nodeIterable))
}
// Access node data using values() or entries()
const nodeData = Array.from(Graph.values(dfsNodes)) // ["A", "B"]
const nodeEntries = Array.from(Graph.entries(allNodes)) // [[0, "A"], [1, "B"]]
Walker((f: (index: number, data: N) => Uf) => ({
[var Symbol: SymbolConstructorSymbol.SymbolConstructor.iterator: typeof Symbol.iteratorA method that returns the default iterator for an object. Called by the semantics of the
for-of statement.
iterator]: () => {
const const inDegree: Map<number, number>inDegree = new var Map: MapConstructor
new <number, number>(iterable?: Iterable<readonly [number, number]> | null | undefined) => Map<number, number> (+3 overloads)
Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, number>()
const const remaining: Set<number>remaining = new var Set: SetConstructor
new <number>(iterable?: Iterable<number> | null | undefined) => Set<number> (+1 overload)
Set<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex>()
const const initialSet: Set<number>initialSet = new var Set: SetConstructor
new <number>(iterable?: Iterable<number> | null | undefined) => Set<number> (+1 overload)
Set(const initials: number[]initials)
const const queue: number[]queue = [...const initials: number[]initials]
// Initialize in-degree counts
for (const [const nodeIndex: numbernodeIndex] of graph: Graph<N, E, T> | MutableGraph<N, E, T>graph.Proto<out N, out E>.nodes: Map<NodeIndex, N>nodes) {
const inDegree: Map<number, number>inDegree.Map<number, number>.set(key: number, value: number): Map<number, number>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const nodeIndex: numbernodeIndex, 0)
const remaining: Set<number>remaining.Set<number>.add(value: number): Set<number>Appends a new element with a specified value to the end of the Set.
add(const nodeIndex: numbernodeIndex)
}
// Calculate in-degrees
for (const [, const edgeData: Edge<E>const edgeData: {
source: number;
target: number;
data: E;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
edgeData] of graph: Graph<N, E, T> | MutableGraph<N, E, T>graph.Proto<out N, out E>.edges: Map<EdgeIndex, Edge<E>>edges) {
const const currentInDegree: numbercurrentInDegree = const inDegree: Map<number, number>inDegree.Map<number, number>.get(key: number): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const edgeData: Edge<E>const edgeData: {
source: number;
target: number;
data: E;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
edgeData.target) || 0
const inDegree: Map<number, number>inDegree.Map<number, number>.set(key: number, value: number): Map<number, number>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const edgeData: Edge<E>const edgeData: {
source: number;
target: number;
data: E;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
edgeData.target, const currentInDegree: numbercurrentInDegree + 1)
}
for (const const nodeIndex: numbernodeIndex of const initials: number[]initials) {
if (const inDegree: Map<number, number>inDegree.Map<number, number>.get(key: number): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const nodeIndex: numbernodeIndex)! !== 0) {
throw new constructor GraphError(): GraphErrorError thrown by graph operations when the requested graph structure is
invalid, such as referencing a missing node or using unsupported edge
weights.
When to use
Use when handling failures thrown by graph operations that reject invalid
graph structure or unsupported algorithm inputs.
GraphError({ message: stringmessage: `Initial node ${const nodeIndex: numbernodeIndex} has incoming edges` })
}
}
// Add remaining zero in-degree nodes after prioritized initials.
for (const [const nodeIndex: numbernodeIndex, const degree: numberdegree] of const inDegree: Map<number, number>inDegree) {
if (const degree: numberdegree === 0 && !const initialSet: Set<number>initialSet.Set<number>.has(value: number): booleanhas(const nodeIndex: numbernodeIndex)) {
const queue: number[]queue.Array<number>.push(...items: number[]): numberAppends new elements to the end of an array, and returns the new length of the array.
push(const nodeIndex: numbernodeIndex)
}
}
const const nextMapped: () =>
| {
done: boolean
value: U
}
| {
readonly done: true
readonly value: undefined
}
nextMapped = () => {
while (const queue: number[]queue.Array<number>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.
length > 0) {
const const current: numbercurrent = const queue: number[]queue.Array<number>.shift(): number | undefinedRemoves the first element from an array and returns it.
If the array is empty, undefined is returned and the array is not modified.
shift()!
if (const remaining: Set<number>remaining.Set<number>.has(value: number): booleanhas(const current: numbercurrent)) {
const remaining: Set<number>remaining.Set<number>.delete(value: number): booleanRemoves a specified value from the Set.
delete(const current: numbercurrent)
// Process outgoing edges, reducing in-degree of targets
const const neighbors: number[]neighbors = const getDirectedNeighbors: <N, E>(
graph:
| Graph<N, E, "directed">
| MutableGraph<N, E, "directed">,
nodeIndex: NodeIndex,
direction: Direction
) => Array<NodeIndex>
getDirectedNeighbors(
graph: Graph<N, E, T> | MutableGraph<N, E, T>graph as interface Graph<out N, out E, T extends Kind = "directed">Immutable graph interface.
When to use
Use as the immutable graph model for code that queries, traverses,
transforms, or analyzes graph structure without mutating it.
Graph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>E, "directed"> | interface MutableGraph<out N, out E, T extends Kind = "directed">Mutable graph interface.
When to use
Use when adding, removing, or updating nodes and edges inside a graph
mutation scope.
MutableGraph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>E, "directed">,
const current: numbercurrent,
"outgoing"
)
for (const const neighbor: numberneighbor of const neighbors: number[]neighbors) {
if (const remaining: Set<number>remaining.Set<number>.has(value: number): booleanhas(const neighbor: numberneighbor)) {
const const currentInDegree: numbercurrentInDegree = const inDegree: Map<number, number>inDegree.Map<number, number>.get(key: number): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const neighbor: numberneighbor) || 0
const const newInDegree: numbernewInDegree = const currentInDegree: numbercurrentInDegree - 1
const inDegree: Map<number, number>inDegree.Map<number, number>.set(key: number, value: number): Map<number, number>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const neighbor: numberneighbor, const newInDegree: numbernewInDegree)
// If in-degree becomes 0, add to queue
if (const newInDegree: numbernewInDegree === 0) {
const queue: number[]queue.Array<number>.push(...items: number[]): numberAppends new elements to the end of an array, and returns the new length of the array.
push(const neighbor: numberneighbor)
}
}
}
const const nodeData: Option.Option<N>nodeData = const getNode: {
<N, E, T extends Kind = "directed">(
nodeIndex: NodeIndex
): (
graph: Graph<N, E, T> | MutableGraph<N, E, T>
) => Option.Option<N>
<N, E, T extends Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>,
nodeIndex: NodeIndex
): Option.Option<N>
}
getNode(graph: Graph<N, E, T> | MutableGraph<N, E, T>graph, const current: numbercurrent)
if (import OptionOption.const isSome: <A>(
self: Option<A>
) => self is Some<A>
Checks whether an Option contains a value (Some).
When to use
Use when you need to branch on a present Option before accessing .value.
Details
- Acts as a type guard, narrowing to
Some<A>
Example (Checking for Some)
import { Option } from "effect"
console.log(Option.isSome(Option.some(1)))
// Output: true
console.log(Option.isSome(Option.none()))
// Output: false
isSome(const nodeData: Option.Option<N>nodeData)) {
return { done: booleandone: false, value: Uvalue: f: (index: number, data: N) => Uf(const current: numbercurrent, const nodeData: Option.Some<N>const nodeData: {
_tag: "Some";
_op: "Some";
value: A;
valueOrUndefined: A;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
nodeData.Some<N>.value: Nvalue) }
}
return const nextMapped: () =>
| {
done: boolean
value: U
}
| {
readonly done: true
readonly value: undefined
}
nextMapped()
}
}
return { done: truedone: true, value: undefinedvalue: var undefinedundefined } as type const = {
readonly done: true;
readonly value: undefined;
}
const
}
return { Iterator<U, any, any>.next(...[value]: [] | [any]): IteratorResult<U, any>next: const nextMapped: () =>
| {
done: boolean
value: U
}
| {
readonly done: true
readonly value: undefined
}
nextMapped }
}
}))
})