Учитывая программу:
import Debug.Trace
main = print $ trace "hit" 1 + trace "hit" 1
Если я скомпилирован с ghc -O (7.0.1 или выше), я получаю вывод:
hit
2
то есть. GHC использовала единую исключение субэкспрессии (CSE), чтобы переписать мою программу как:
main = print $ let x = trace "hit" 1 in x + x
Если я скомпилирую с -fno-cse, я вижу, что hit появляется дважды.
Можно ли избежать CSE, изменив программу? Есть ли какое-либо подвыражение e, для которого я могу гарантировать, что e + e не будет CSE'd? Я знаю о lazy, но не может найти ничего, предназначенное для блокировки CSE.
Фон этого вопроса - библиотека cmdargs, где CSE разбивает библиотеку (из-за нечистоты в библиотеке). Одно из решений - попросить пользователей библиотеки указать -fno-cse, но я бы предпочел изменить библиотеку.