2017-11-24 3 views
0

Ich bin verwirrt über den Kompilierfehler für die Zeile, die endState definiert. Hier ist der Code:Scala ADT Type Mismatch

import java.util.UUID 

object Evaluation { 
    def default: Evaluation[Unit, Unit] = new Evaluation[Unit, Unit](identity) 
} 

case class Evaluation[From, +To](evaluate: (From) => To) 

object FSMLike { 
    val uuidEmpty: UUID = new UUID(0L, 0L) 

    val endState: Evaluation[Unit, FSMLike[Nothing]] = new Evaluation(() => FSMEmpty) 

    lazy val stop: FSMEntry[Unit, Unit, Nothing] = FSMEntry(uuidEmpty, Evaluation.default, endState) 

    def apply[From1, From2, To](
    action: Evaluation[From1, Unit], 
    nextState: Evaluation[From2, FSMLike[To]] 
): (UUID, FSMLike[To]) = { 
    val uuid = UUID.randomUUID 
    uuid -> FSMEntry(uuid, action, nextState) 
    } 
} 

sealed trait FSMLike[+A] 

case object FSMEmpty extends FSMLike[Nothing] 

case class FSMEntry[From1, From2, +To](
    id: UUID, 
    action: Evaluation[From1, Unit], 
    nextState: Evaluation[From2, FSMLike[To]] 
) extends FSMLike[To] { 
    def transition(arg1: From1, arg2: From2): FSMLike[To] = { 
    action.evaluate(arg1) 
    nextState.evaluate(arg2) 
    } 

    override def toString: String = s"^$id^" 
} 

Hier ist der Fehler:

Error:(14, 72) type mismatch; 
found :() => FSMEmpty.type (with underlying type() => FSMEmpty.type) 
required: Unit => FSMLike[Nothing] 
    val endState: Evaluation[Unit, FSMLike[Nothing]] = new Evaluation(() => FSMEmpty) 

Antwort

2

Sie versuchen () => FSMEmpty zu passieren, eine Funktion ohne Argumente, in dem eine Funktion mit einem Argument vom Typ Unit erwartet wird. Sicher, wenn Sie () als Ausdruck verwenden, ist es der einzige Wert des Typs Unit, aber die linke Seite von => ist kein Ausdruck.

Sie sollten stattdessen _ => FSMEmpty schreiben. { case() => FSMEmpty } würde auch funktionieren, denke ich, aber es gibt nicht viel Sinn es zu benutzen.

+0

Ausgezeichnete Antwort, sehr aufschlussreich, danke! –