Ich suche nach einer eleganten Möglichkeit, Teilfunktionen zu verketten, die von einem gemeinsamen Basistyp abgeleitet sind. Die Idee ist, dass jeder Teilfunktion eine Art behandelt, so dass sie leicht werden für verschiedene Arten zu komponieren und haben eine gemeinsame catch-all, wenn die verkettete Teilfunktion nicht definiert ist:Elegante Möglichkeit, Scala Teilfunktionen zu verketten
trait Message
trait SysMessage extends Message
trait UserMessage extends Message
case class TextSysMessage(m: String) extends SysMessage
case class TextUserMessage(m: String) extends UserMessage
class Test {
type MessagePF = scala.PartialFunction[Message, String]
type SysMessagePF = scala.PartialFunction[SysMessage, String]
type UserMessagePF = scala.PartialFunction[UserMessage, String]
def getSysMessage: SysMessagePF = {
case sm: TextSysMessage ⇒ s"System message: ${sm.m}"
}
def getUserMessage: UserMessagePF = {
case um: TextUserMessage ⇒ s"User message: ${um.m}"
}
def * : MessagePF = {
case m ⇒ s"Unknown message: $m"
}
// Chained partials fails because `m` is a SysMessage with UserMessage
def handler(m: Message): String = (getSysMessage orElse getUserMessage orElse *)(m)
}
Offensichtlich ist dieser Ansatz nicht kompiliert. Ich kann durch verschachtelte Muster wie diese
def getSysMessage: MessagePF = {
case m: SysMessage ⇒ m match {
case sm: TextSysMessage ⇒ s"System message: ${sm.m}"
}
}
passend dieses Problem umgehen, aber dann verliere ich die Fähigkeit, alle in einem Fang unbekannte Umgang mit Nachrichten. Gibt es einen eleganten Weg, dieses Ziel zu erreichen?
type MessagePF = scala.PartialFunction[Message, String]
type SysMessagePF = scala.PartialFunction[Message, String]
type UserMessagePF = scala.PartialFunction[Message, String]
Warum nicht jede 'PartialFunction' mit' Message' als Eingabetyp definieren? – adamwy
Das ist im Wesentlichen Plan B .... –
Aber wie können Sie sogar eine partielle Funktion erwarten, die konkreten Subtyp mit arbiträren 'Message' arbeiten lässt? Etwas wie 'def handler (m: Nachricht): String = (getSysMessage) (m)' wird auch nicht funktionieren. – adamwy