Хороший способ не делиться?

Предположим, что кто-то переведет этот простой код Python на Haskell:

def important_astrological_calculation(digits):
  # Get the first 1000000 digits of Pi!
  lucky_numbers = calculate_first_digits_of_pi(1000000)
  return digits in lucky_numbers

Хаскель версия:

importantAstrologicalCalculation digits =
  isInfixOf digits luckyNumbers
  where
    luckyNumbers = calculateFirstDigitsOfPi 1000000

После работы с версией для Haskell программист с удивлением обнаруживает, что его версия для Haskell «пропускает» память — после первого вызова его функции luckyNumbers никогда не освобождается. Это беспокоит, так как программа включает в себя еще несколько подобных функций, и память, потребляемая всеми ими, значительна.

Есть ли простой и элегантный способ заставить программу «забыть» luckyNumbers?


person yairchu    schedule 07.07.2011    source источник
comment
Не элегантно, но что произойдет, если вы добавите {-# NOINLINE importantAstrologicalCalculation #-}?   -  person John L    schedule 07.07.2011
comment
Недавно был вопрос, задающий вроде бы то же самое, но используя более продвинутую терминологию. Вы можете взглянуть на это: stackoverflow.com/questions/6090932/   -  person Rotsor    schedule 07.07.2011


Ответы (1)


В этом случае ваш список пицифр является константой (или «постоянной аппликативной формой»), и GHC, вероятно, выдаст ее, вычислит один раз и разделит между пользователями. Если нет ссылок на CAF, он будет удален сборщиком мусора.

Теперь, в общем, если вы хотите что-то пересчитать, превратите это в функцию (например, добавив фиктивный параметр ()). Примеры в связанном вопросе о CAF: Как сделать CAF не является CAF в Haskell?

person Don Stewart    schedule 07.07.2011
comment
Вывод из строя что-то меняет? stackoverflow.com/questions/6208006 создает аналогичную ситуацию, но ничего не является константой. - person yairchu; 09.07.2011