2016-08-29 12 views
0

Скажем, у меня есть наивности реализована функция так:Как сказать, что общее уничтожение подвыражения происходит или нет в GHC?

quadratic a b c = (ans1, ans2) 
    where 
    ans1 = ((-b) + sqrt (b * b - 4 * a * c))/(2 * a) 
    ans2 = ((-b) - sqrt (b * b - 4 * a * c))/(2 * a) 

Есть несколько одинаковых подвыражения. Как я могу сказать, не читая ядро, что происходит общее уничтожение подвыражения или нет, и к каким частям этого?

+0

Я считаю, что «читая ядро» является ответом. Почему бы вам не сделать это? Вы можете угадать, вставив функции из 'Debug.Trace', но я бы не стал полагаться на это. – jberryman

+0

@jberryman Существуют ли правила большого пальца, указывающие, какой код вероятен или вряд ли будет оптимизирован? – rityzmon

+0

Несвязанный, но недетерминированность моделируется списками, а не кортежами. 'квадратичный a b c = [ans1, ans2], где ...' – chepner

ответ

3

Использование trace может сообщать вам, как показано в this SO question.

import Debug.Trace 

quadratic a b c = (ans1, ans2) 
    where 
    ans1 = ((-b) + tr1 (sqrt (b * b - 4 * a * c)))/(2 * a) 
    ans2 = ((-b) - tr2 (sqrt (b * b - 4 * a * c)))/(2 * a) 
    tr1 = trace "ans1" 
    tr2 = trace "ans2" 

main = print $ quadratic 1 10 3 

Сборка этого с -O2 или -O3 показывает, как ans1 и ans2 в выходных данных трассировки, указывающий, что GHC не выполняют CSE. Вы получаете аналогичные результаты , если вы используете tr1 в обоих местах.

Haskell Wiki упоминает, что GHC выполняет только CSE в ограниченных обстоятельствах - (link) - и что вам рекомендуется выполнять это самостоятельно, если вы хотите, чтобы убедиться, что это произойдет.