ErikR und John Coleman haben bereits beantwortet die wichtigsten Teile Ihrer Frage aber würde Ich mag etwas zusätzlich hinweisen:
Es ist am besten Ihre Funktionen in einer Art und Weise zu schreiben, dass sie einfach hängen nicht über die Endlichkeit oder Unendlichkeit ihrer Eingaben - manchmal ist es unmöglich, aber oft ist es nur eine Frage der Neugestaltung. Anstatt beispielsweise den Durchschnitt der gesamten Liste zu berechnen, können Sie einen laufenden Durchschnitt berechnen, der selbst eine Liste ist. und diese Liste wird selbst unendlich sein, wenn die Eingabeliste unendlich und ansonsten endlich ist.
avg :: [Double] -> [Double]
avg = drop 1 . scanl f 0.0 . zip [0..]
where f avg (n, i) = avg * (dbl n/dbl n') +
i /dbl n' where n' = n+1
dbl = fromInteger
, in dem Fall, dass Sie eine unendliche Liste Durchschnitt konnten, nicht seine length
nehmen:
*Main> take 10 $ avg [1..]
[1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0]
Mit anderen Worten, ist eine Option, wie viel von Ihren Funktionen zu entwerfen, einfach sich nicht um den Unendlichkeitsaspekt kümmern und die (vollständige) Auswertung von Listen und anderen (möglicherweise unendlichen) Datenstrukturen so spät wie möglich in Ihrem Programm verzögern.
Auf diese Weise, denke ich, werden sie auch wiederverwendbar und zusammensetzbar sein - alles mit weniger oder mehr allgemeinen Annahmen über seine Eingaben, neigt dazu, mehr zusammensetzbar zu sein; Umgekehrt neigt alles mit mehr oder mehr spezifischen Annahmen dazu, weniger zusammensetzbar und daher weniger wiederverwendbar zu sein.
Es fühlt sich einfach komisch an. Warum existiert die Längenfunktion überhaupt, wenn Sie sie nicht einfach benutzen können? – ais
Nun - was würdest du gerne "Länge" einer unendlichen Liste zurückgeben? – ErikR
Ich würde es vorziehen, wenn die Länge keine unendlichen Listen akzeptiert und einen Typ wie "FiniteList a -> Int''' hat. – ais