Jeder von uns erbt von seinen biologischen Eltern eine Reihe chemischer Anweisungen, die als DNA bekannt sind. Sie beeinflussen, wie unser Körper aufgebaut ist. Alles bekannte Leben hängt von der DNA ab!
Hinweis: Du musst nichts über Nukleotide oder DNA verstehen, um diese Übung zu lösen.
Die DNA ist eine lange Kette anderer Chemikalien, und die wichtigsten sind die vier Nukleotide Adenin, Cytosin, Guanin und Thymin. Eine einzelne DNA-Kette kann Milliarden dieser vier Nukleotide enthalten, und die Reihenfolge, in der sie vorkommen, ist wichtig! Die Reihenfolge dieser Nukleotide in einem Stück DNA nennen wir eine „DNA-Sequenz“.
Wir stellen eine DNA-Sequenz als geordnete Sammlung dieser vier Nukleotide dar. Eine übliche Methode dafür ist ein String aus Zeichen wie „ATTACG“ für eine DNA-Sequenz aus 6 Nukleotiden. „A“ für Adenin, „C“ für Cytosin, „G“ für Guanin und „T“ für Thymin.
Gegeben ist ein String, der eine DNA-Sequenz darstellt. Zähle, wie oft jedes der Nukleotide darin vorkommt. Enthält der String Zeichen, die nicht A, C, G oder T sind, ist er ungültig, und du solltest einen Fehler melden.
Zum Beispiel:
"GATTACA" -> 'A': 3, 'C': 1, 'G': 1, 'T': 2
"INVALID" -> error
Eine häufige Verwendung von Either ist es, eine Berechnung anzugeben, die möglicherweise zu einem Fehler führt (wenn der tatsächliche Fehler nicht von Interesse ist, ist der einfachere Typ Option vielleicht die bessere Wahl). Wenn kein Fehler vorliegt, ist das Ergebnis normalerweise ein Right (Eselsbrücke: der „richtige“ Wert), während ein Fehler ein Left ist, zum Beispiel ein Left[String], das eine Fehlermeldung enthält.
Beachte, dass Either in Scala 2.12 standardmäßig nach rechts ausgerichtet ist, sodass es für Operationen wie filter, map, flatMap oder in einer For-Comprehension wie erwartet funktioniert.
Wenn dir Either nicht vertraut ist, kannst du dieses Tutorial lesen. Beachte aber, dass dieses Tutorial Scala-Versionen vor 2.12 behandelt. In Scala 2.12 kannst du RightProjection getrost ignorieren und .right weglassen.
Either ist eine sogenannte Monade, die einen „Berechnungsaspekt“ abdeckt, in diesem Fall die Fehlerbehandlung.
Der richtige Einsatz von Monaden kann zu sehr prägnantem, aber elegantem
und lesbarem Code führen. Falscher Einsatz kann leicht das Gegenteil bewirken.
Sieh dir dieses Video an, um mehr zu erfahren.
Für Either gibt es ein paar Faustregeln:
def add1(x: Int): Either[String, Int] = Right(x + 1)
besser
def add1(x: Int): Int = x + 1
(es gibt Either.map, um solche einfachen Funktionen anzuwenden,
damit du sie nicht mit Either überladen musst).
isLeft/isRight oder Pattern Matching. Zum Beispiel stattval x: Either[String, Int] = ...
if (x.isRight) x.right.get + 1 else x.left.get
// or
x match {
case Right(n) => n + 1
case Left(s) => s
}
besser
x fold (identity, _ + 1)
Either-Instanzen „zusammensetzen“ möchtest. Stattval xo: Either[String, Int] = ...
val yo: Either[String, Int] = ...
val zo: Either[String, Int] = ...
xo.flatMap(x =>
yo.flatMap(y =>
zo.map(z =>
x + y + z)))
besser
for {
x <- xo
y <- yo
z <- zo
} yield x + y + z
Melde dich bei Exercism an, um Scala mit 95 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.