Учитывая программу:
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
, но я бы предпочел изменить библиотеку.