0

I'm trying to do a simple Dijkstra pathfinder with genericly typed nodes. For this I have my pathfinder class and a nested data class to help. It look like this

class Dijkstra<T, U: Number >(  val graph: Graph<T, U>,
                                val from: Node<T, U>,
                                val to: Node<T, U>) {

    private var nodesDistances = mutableMapOf<Node<T, U>, DijkstraDistanceHelper<T, U>>()

    init {
        graph.getNodeList().forEach { nodesDistances[it] = DijkstraDistanceHelper<T, U>(it, null, null) }

        val currentNode = from

        while (currentNode != to) {
            currentNode.getNeighborhood()?.forEach {
                if (it.destination != currentNode) {
                    //it.value type is U and properly recognized as such
                    val currentDistance = it.value + (nodesDistances[currentNode]!!.distance ?: 0)

                    if (nodesDistances[it.destination]?.distance == null
                        || nodesDistances[it.destination]!!.distance!! > currentDistance) {
                        //compilator error on the compare too, same reason I assume
                        nodesDistances[it.destination]!!.distance = currentDistance
                        nodesDistances[it.destination]!!.parentNode = currentNode
                    }
                }
            }
        }
    }

    private data class DijkstraDistanceHelper<T, U: Number>(  val node: Node<T, U>,
                                                              var distance: U?,
                                                              var parentNode: Node<T, U>?)
}

This is not sound algorithmically speaking but what bother me is that it doesn't compile : the compilator can't comprehend that Dijkstra's U generic type is the same as DijkstraDistanceHelper

Is it the wrong way? How can I enforce that Dijkstra's generic types (both T and U) are the same as DijkstraDistanceHelper?

1 Answer 1

1

There is no way to add abstract Number instances. If you look at the documentation you will see that no plus operator has been defined. This is because adding numbers has different behaviour depending on whether they are floating point and their internal size.

You will need to provide the method to add the U instances, something like (U,U) -> U as a parameter which can be provided during creation as Int::plus or its equivalent.

Sign up to request clarification or add additional context in comments.

2 Comments

I know this but I'd like for DijkstraDistanceHelper to use Dijkstra's generics types.I don't want to redefine them. That way when Dijkstra's U is an Int, DijkstraDistanceHelper's U is also an Int and can't be something else
Yes, but the language cannot know that U is Int, so what is Number + Number supposed to do?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.