Учитывая программу:
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
появляется дважды.
Можно ли избежать ЕГЭ, изменив программу? Есть ли подвыражение e
, для которого я могу гарантировать, что e + e
не будет подвергнуто CSE? Я знаю о lazy
, но не могу найти ничего, предназначенного для подавления CSE.
Предысторией этого вопроса является библиотека cmdargs, где CSE ломает библиотеку (из-за нечистоты в библиотека). Одно из решений — попросить пользователей библиотеки указать -fno-cse
, но я бы предпочел изменить библиотеку.
-fno-ignore-asserts
. - person Neil Mitchell   schedule 07.05.2011(due to impurity in the library)
. Очевидно, что поскольку это нарушает семантику Haskell, компиляторы запутаются. Нет ли способа реорганизовать ваш код, чтобы сделать его ссылочно прозрачным так, чтобы его мог понять компилятор? Например. Монада ST или сделать ее чистой? - person Don Stewart   schedule 07.05.2011opt "example"
, из пользовательского кода (см. здесь). Поскольку пользовательский код может быть чем угодно, это должно нарушать ссылочную прозрачность по замыслу. Довольно крутой хак, но очень хрупкий. - person Peter Wortmann   schedule 07.05.2011