ErikR и John Coleman уже ответили на основные части вашего вопроса, однако я хотел бы отметить еще кое-что:
Лучше всего писать свои функции таким образом, чтобы они просто не зависели от конечности или бесконечности своих входных данных — иногда это невозможно, но в большинстве случаев это просто вопрос редизайна. Например, вместо вычисления среднего значения всего списка вы можете вычислить скользящее среднее значение, которое само по себе является списком; и сам этот список будет бесконечным, если входной список бесконечен, и конечным в противном случае.
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
в этом случае вы можете усреднять бесконечный список, не беря его length
:
*Main> take 10 $ avg [1..]
[1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0]
Другими словами, один из вариантов состоит в том, чтобы спроектировать как можно больше ваших функций, чтобы они просто не заботились о аспекте бесконечности и откладывали (полную) оценку списков и других (потенциально бесконечных) структур данных до самой поздней фазы в вашей программе. насколько это возможно.
Таким образом, они также будут более пригодными для повторного использования и компоновки — все, что имеет меньше или более общих предположений о входных данных, имеет тенденцию быть более компонуемым; и наоборот, что-либо с более или более конкретными предположениями, как правило, менее компонуемо и, следовательно, менее пригодно для повторного использования.
person
Erik Kaplun
schedule
08.10.2015