ОК, так что это беспокоило меня какое-то время, поэтому я подумал, что приду и спрошу кого-нибудь, кто мог бы действительно узнать ответ.Выполнение подвыражения один раз
Пусть у меня есть следующие функции:
foobar x y = expensive x + cheap y
Предположим, далее, что часть программы занимает foobar 5
в качестве входных данных, и выполняет эту функцию миллионы раз в тугой петлей. Понятно, что я хочу, чтобы expensive 5
был вычислен один раз, а не миллион раз.
Я мог бы оставить код, как это, или я мог бы изменить его
foobar x = let k = expensive x in \ y -> k + cheap y
Это оставляет мне интересно ...
Является GHC достаточно умен, чтобы устранить дублированную работу сам? (I.e., делает ли первая версия делать то, что я хочу?)
Если нет, делает ли вторая версия на самом деле проблему? (Т.е., будет Оптимизатор просто превратить его обратно в тот же код, как первый вариант?)
Не может ли это изменить семантику, 'map (foo 5) []; foo a b = undefined a + b' Если вы вынудите оценку 'foo 5' для карты, вы будете излишне ненужным – jozefg
@jozefg' let' не заставляет оценивать. Он оценивается, когда он необходим в первый раз (и, как мы надеемся, будет использоваться для дальнейшего использования). –