Ich schreibe ein Programm über die Klassifizierung von musikalischen Intervallen. Die konzeptionelle Struktur ist ziemlich kompliziert und ich würde sie so klar wie möglich darstellen. Die ersten paar Codezeilen sind ein kleiner Auszug, der richtig funktioniert. Der zweite ist der Pseudo-Code, der meinen Bedürfnissen der Prägnanz entspricht.Gibt es in Haskell sowas wie Unterwächter?
interval pt1 pt2
| gd == 0 && sd < (-2) = ("unison",show (abs sd) ++ "d")
| gd == 0 && sd == (-2) = ("unison","dd")
| gd == 0 && sd == (-1) = ("unison","d")
| gd == 0 && sd == 0 = ("unison","P")
| gd == 0 && sd == 1 = ("unison","A")
| gd == 0 && sd == 2 = ("unison","AA")
| gd == 0 && sd > 2 = ("unison",show sd ++ "A")
| gd == 1 && sd < (-1) = ("second",show (abs sd) ++ "d")
| gd == 1 && sd == (-1) = ("second","dd")
| gd == 1 && sd == 0 = ("second","d")
| gd == 1 && sd == 1 = ("second","m")
| gd == 1 && sd == 2 = ("second","M")
| gd == 1 && sd == 3 = ("second","A")
| gd == 1 && sd == 4 = ("second","AA")
| gd == 1 && sd > 4 = ("second",show (abs sd) ++ "A")
where
(bn1,acc1,oct1) = parsePitch pt1
(bn2,acc2,oct2) = parsePitch pt2
direction = signum sd
sd = displacementInSemitonesOfPitches pt1 pt2
gd = abs $ displacementBetweenTwoBaseNotes direction bn1 bn2
Gibt es eine Programmstruktur, die den Code vereinfachen könnte wie der folgende Pseudo-Code macht?
interval pt1 pt2
| gd == 0 | sd < (-2) = ("unison",show (abs sd) ++ "d")
| sd == (-2) = ("unison","dd")
| sd == (-1) = ("unison","d")
| sd == 0 = ("unison","P")
| sd == 1 = ("unison","A")
| sd == 2 = ("unison","AA")
| sd > 2 = ("unison",show sd ++ "A")
| gd == 1 | sd < (-1) = ("second",show (abs sd) ++ "d")
| sd == (-1) = ("second","dd")
| sd == 0 = ("second","d")
| sd == 1 = ("second","m")
| sd == 2 = ("second","M")
| sd == 3 = ("second","A")
| sd == 4 = ("second","AA")
| sd > 4 = ("second",show (abs sd) ++ "A")
| gd == 2 | sd ... = ...
| sd ... = ...
...
| mod gd 7 == 1 | mod sd 12 == ...
| mod sd 12 == ...
...
| otherwise = ...
where
(bn1,acc1,oct1) = parsePitch pt1
(bn2,acc2,oct2) = parsePitch pt2
direction = signum sd
sd = displacementInSemitonesOfPitches pt1 pt2
gd = abs $ displacementBetweenTwoBaseNotes direction bn1 bn2
Vielen Dank im Voraus für Ihre Vorschläge.
Dies scheint ein bisschen wie Betrug zu sein, denn der einzige Grund, warum Sie keine Warnung erhalten, ist, dass 'fromJust' einen Fehlerzweig hat, den Sie nicht zu übernehmen versprechen. – dfeuer
Was ich denke ist, dass vielleicht eine Fortsetzungs-Monade oder etwas ähnliches verwendet werden könnte, um die Hässlichkeit von expliziten Join-Punkten zu verbergen. – dfeuer
@dfeuer Ich stimme der Verwendung von "fromJust" als hässlich zu. OTOH, wir kodieren Multiway-Fall, der von Natur aus teilweise ist. Wenn wir annehmen könnten, dass der letzte Fall ein Catch-All-Fall ist ('Other'), könnten wir' may' anstelle von 'fromJust' verwenden, so dass wir keine Teilfunktionen verwenden. – chi