Кажется, я не понимаю систему типа Scala. Я пытаюсь реализовать две основные черты и черту для семейства алгоритмов для работы с ними. Что я делаю неправильно в ниже?
Базовые признаки для движений & состояний; они упрощены, чтобы просто включать методы, которые раскрывают проблему.
trait Move
trait State[M <: Move] {
def moves: List[M]
def successor(m: M): State[M]
}
Вот черта для семейства алгоритмов, использующих выше. Я не уверен, что это правильно! Возможно, некоторые из них связаны с CN00/CN01.
trait Algorithm {
def bestMove[M <: Move, S <: State[M]](s: S): M
}
Бетонный ход и состояние:
case class MyMove(x: Int) extends Move
class MyState(val s: Map[MyMove,Int]) extends State[MyMove] {
def moves = MyMove(1) :: MyMove(2) :: Nil
def successor(p: MyMove) = new MyState(s.updated(p, 1))
}
Я нахожусь на очень шаткой почве относительно ниже, но компилятор, кажется, согласен с этим... Попытка сделать конкретную реализацию признака Алгоритма.
object MyAlgorithm extends Algorithm {
def bestMove(s: State[Move]) = s.moves.head
}
Пока нет ошибок компиляции; они появляются, когда я пытаюсь собрать все части вместе:
object Main extends App {
val s = new MyState(Map())
val m = MyAlgorithm.bestMove(s)
println(m)
}
Вышеупомянутая ошибка:
error: overloaded method value bestMove with alternatives:
(s: State[Move])Move <and>
[M <: Move, S <: State[M]](s: S)M
cannot be applied to (MyState)
val m = MyAlgorithm.bestMove(s)
^
Обновление: я изменил черту алгоритма, чтобы использовать элементы абстрактного типа, как это было предложено. Это решило вопрос, как я его сформулировал, но я немного упростил его. Метод MyAlgorithm.bestMove()
должен иметь возможность вызывать себя с выходом из s.successor(m), например:
trait Algorithm {
type M <: Move
type S <: State[M]
def bestMove(s: S): M
}
trait MyAlgorithm extends Algorithm {
def score(s: S): Int = s.moves.size
def bestMove(s: S): M = {
val groups = s.moves.groupBy(m => score(s.successor(m)))
val max = groups.keys.max
groups(max).head
}
}
Приведенное выше дает 2 ошибки:
Foo.scala:38: error: type mismatch;
found : State[MyAlgorithm.this.M]
required: MyAlgorithm.this.S
val groups = s.moves.groupBy(m => score(s.successor(m)))
^
Foo.scala:39: error: diverging implicit expansion for type Ordering[B]
starting with method Tuple9 in object Ordering
val max = groups.keys.max
^
Должен ли я перейти к подходу, используя черты признаков, например, шаблон Cake, чтобы сделать эту работу? (Я просто догадываюсь, я все еще смущен.)