Ich beschäftige mich derzeit mit einer Funktion, die so aussieht:
foo = (\(a:b:c:d:e:f:_) -> foobar a b c d e f) . (++ repeat def)
Mit anderen Worten, bei einer gegebenen Liste werden die ersten sechs Elemente für etwas verwendet, und wenn die Liste weniger als sechs Elemente lang ist, wird sie def
als Ersatz für die fehlenden Elemente verwendet . Das ist total, aber die Teile davon sind nicht (genau wie map fromJust . filter isJust
), also mag ich es nicht. Ich habe versucht, dies so umzuschreiben, dass keine Parteilichkeit erforderlich ist, und habe Folgendes erhalten:
foo [] = foobar def def def def def def
foo [a] = foobar a def def def def def
foo [a,b] = foobar a b def def def def
foo [a,b,c] = foobar a b c def def def
foo [a,b,c,d] = foobar a b c d def def
foo [a,b,c,d,e] = foobar a b c d e def
foo (a:b:c:d:e:f:_) = foobar a b c d e f
Ich habe technisch getan, was ich will, aber jetzt ist das ein gigantisches Durcheinander. Wie kann ich dies eleganter und weniger repetitiv tun?
case xs ++ repeat def of a:b:c:d:e:f:_ -> ...
lokal genug ist, dass ich nicht zweimal darüber nachdenken würde, es einfach zu verwenden und alle zusätzlichen Maschinen zu überspringen, die die vorhandenen Antworten einführen. Es sind im Allgemeinen die globaleren Totalitätsargumente (die Invarianten beinhalten, die über mehrere Funktionsaufrufe hinweg beibehalten werden, z. B.), die mich nervös machen.
takeWithDef
ist es nicht verwendbar, wenn es eine reguläre Liste zurückgibt, da wir das Muster übereinstimmen müssen: - / Die richtige Lösung ist das, was Daniel unten in seiner zweiten Antwort geschrieben hat. uncons
bekommt nur das erste Element, also ist es nicht so nützlich.
uncons :: Default a => [a] -> (a,[a])
die standardmäßig istdef
. Oder eine StandardeinstellungtakeWithDef
. Und / oder ein Ansichtsmuster / Mustersynonym. Dies erfordert jedoch das Schreiben eines zusätzlichen Hilfecodes.