patternMinor
Removing asInstance[T] from scala code
Viewed 0 times
removingscalaasinstancecodefrom
Problem
I've written this scala code and I cannot work out how/if it is possible to remove the
The basic idea is that there are two hierarchies
and
These hierarchies will branched in the future, but at the moment there is only one concrete class and its direct parents.
The aim is to be able to just call
As it stands, the code works fine for all the examples I have tried.
I think that it is correct to say in the type declaration of
So, is there a better way of doing it. Should I be prepared for unforeseen consequences?
`object test {
abstract class SolutionFinder[T
asInstance in the definition of class Problem.The basic idea is that there are two hierarchies
Problem
SpecificProblem
ConcreteSpecificProblemand
SolutionFinder
SpecificSolutionFinder
ConcreteSpecificSolutionFinderThese hierarchies will branched in the future, but at the moment there is only one concrete class and its direct parents.
SolutionFinder classes operate on Problem classes, and on construction of a Problem we provide a SolutionFinder instance that we will operate on it. The type declaration of the Problem class/subclasses specifies which SolutionFinder subclass be used on it, and the SolutionFinder type declaration specifies which Problem classes it be applied to. The aim is to be able to just call
solve on any kind of Problem and have it use the appropriate methods.As it stands, the code works fine for all the examples I have tried.
I think that it is correct to say in the type declaration of
Problem, it is implicit (in the non-scala-keyword sense) that S = S[S,T] = Problem[S,T]. The compiler does not recognise this, perhaps because I'm wrong about this and perhaps because this level of recursive type definition is beyond it's capabilities. To get around this I have told it to convert this to an S using asInstance, which is a faux-pas which I would like to avoid. So, is there a better way of doing it. Should I be prepared for unforeseen consequences?
`object test {
abstract class SolutionFinder[T
Solution
There is no implicit inference that
A better design might be to disentangle the
If you need a more sophisticated relation between
S = S[S,T] = Problem[S,T]. But you can add an explicit one:abstract class Problem[T
def solve(): Unit = solutionFinder.findSolution(this)
}A better design might be to disentangle the
Problem and Solution. Perhaps the solve could be moved out of Problem, and require the Solution only at the point of use?trait Problem
trait Solution[P <: Problem] {def solve(p: P): Unit }
class ConcreteProblem extends Problem
class ConcreteSolution extends Solution[ConcreteProblem]
def solve[P <: Problem](p: P, s: Solution[P]) = s.solve(p)If you need a more sophisticated relation between
Problem and Solution, you could create a typeclass for the "relationship", with implicit instances available:trait KnowsHowToSolve[P <: Problem, S <: Solution] {
def solve(p: P, s: S): Unit
}
implicit object ConcreteProblemKnowsHowToSolveConcreteSolution extends KnowsHowToSolve[ConcreteProblem, ConcreteSolution] {
def solve(p: ConcreteProblem, s: ConcreteSolution) = s.findSpecificSolution(p)
}
def solve[P <: Problem, S <: Solution](p: P, s: S)(implicit ks: P KnowsHowToSolve S) = ...Code Snippets
abstract class Problem[T <: SolutionFinder[S, T], S <: Problem[T, S]](solutionFinder: T) {
this: S =>
def solve(): Unit = solutionFinder.findSolution(this)
}trait Problem
trait Solution[P <: Problem] {def solve(p: P): Unit }
class ConcreteProblem extends Problem
class ConcreteSolution extends Solution[ConcreteProblem]
def solve[P <: Problem](p: P, s: Solution[P]) = s.solve(p)trait KnowsHowToSolve[P <: Problem, S <: Solution] {
def solve(p: P, s: S): Unit
}
implicit object ConcreteProblemKnowsHowToSolveConcreteSolution extends KnowsHowToSolve[ConcreteProblem, ConcreteSolution] {
def solve(p: ConcreteProblem, s: ConcreteSolution) = s.findSpecificSolution(p)
}
def solve[P <: Problem, S <: Solution](p: P, s: S)(implicit ks: P KnowsHowToSolve S) = ...Context
StackExchange Code Review Q#66852, answer score: 3
Revisions (0)
No revisions yet.