I'm working on a library that implement a couple of generic graph types. I'm currently working on creating a clean style of instantiation.
My goal is to create a graph like such:
val graph = graphOf<Int>(true) {
1 to setOf(2,3,4,)
2 to setOf(1,3,4,)
3 to emptySet<Int>()
4 to emptySet<Int>()
}
Which would create a graph with 4 vertices (1 ... 4) where 1 and 2 are connected to all the other vertices, and 3 and 4 are not connected to any. I thought this would be the cleanest and most ergonomic style. It doesn't fill the underlying map though. I know it is possible to build a map like this, because I've this kind of DSL somewhere before, but I'm struggling to figure out how.
The code that is called:
fun <Vertex> graphOf(
isDirected: Boolean,
vertexEdgeMap: MutableMap<Vertex, Set<Vertex>>.() -> Unit // I think the problem lies here?
) = graphOf(isDirected, mutableMapOf<Vertex, Set<Vertex>>().also(vertexEdgeMap))
fun <Vertex> graphOf(
isDirected: Boolean,
vertexEdgeMap: Map<Vertex, Set<Vertex>> = emptyMap()
): Graph<Vertex> = mutableGraphOf(isDirected, vertexEdgeMap)
fun <Vertex> mutableGraphOf(
isDirected: Boolean,
vertexEdgeMap: Map<Vertex, Set<Vertex>> = emptyMap()
): MutableGraph<Vertex> = MutableAdjacencyMapGraphImpl<Vertex>(isDirected)
.apply {
vertexEdgeMap.forEach { addVertex(it.key) }
vertexEdgeMap.forEach {
from -> from.value.forEach {
to -> addEdge(from.key, to) }
}
}
Anyone got any tips?
The following will allow you to write "graphOf" in a similar way you mentioned.
I overrided "to" function infix fun T.to(that: Set<T>)
Look if it helps.
class GraphBuilder<T> {
val graph: MutableMap<T, Set<T>> = mutableMapOf()
infix fun T.to(that: Set<T>): GraphBuilder<T> {
val graphBuilder = this@GraphBuilder
graphBuilder.graph.put(this, that)
return graphBuilder
}
}
fun <T> graphOf(pair: GraphBuilder<T>.() -> Unit): GraphBuilder<T> {
val builder = GraphBuilder<T>()
pair(builder)
return builder
}
fun main() {
val graph =
graphOf<Int>() {
1 to setOf(2, 3, 4)
2 to setOf(1, 3, 4)
3 to emptySet()
4 to emptySet()
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.