лень и функциональная композиция (haskell, erlang) - PullRequest
9 голосов
/ 27 января 2012

Может кто-нибудь объяснить или дать некоторые ресурсы о том, как работает композиция функций в отношении лени?

Например, как filter (/='W') . map toUpper $ "justaword" работает в Haskell по сравнению с его аналогом в Erlang, который не ленив?

1 Ответ

13 голосов
/ 27 января 2012

Каждый раз, когда требуется другой символ (или уведомление о завершении), следующий символ - если таковой имеется - отображается в верхнем регистре, который сравнивается с буквой «W», если он получен неравным.

filter (/= 'W') . map toUpper $ "justaword"
~> filter (/= 'W') (toUpper 'j' : map toUpper "ustaword")
~> filter (/= 'W') ('J' : map toUpper "ustaword")
~> 'J' : filter (/= 'W') (map toUpper "ustaword")

Теперь доступен первый символ, поэтому для запросов, таких как null или функций, таких как take 1, дальнейшая работа не выполняется. Если потребителю потребуется больше символов, они будут создаваться один за другим, пока не будет достигнут конец строки.

Пример:

Prelude Data.Char> take 10 . filter (/= 'W') . map toUpper $ repeat 't'
"TTTTTTTTTT"

repeat создает бесконечный список, но пока используется только конечная часть, вычисление заканчивается за конечное время. Однако take 10 . filter (/= 'W') . map toUpper $ repeat 'w' не будет завершен, поскольку ни один из произведенных символов не проходит filter, чтобы достичь take 10.

...