Выполнение отложенной оценки в Haskell, когда аргументы появляются несколько раз - PullRequest
8 голосов
/ 11 октября 2011

Допустим, у меня есть функция, которая может вычислить мощность четырех из числа, определенного как

let power4 x = x*x*x*x

И я пытаюсь передать х = (3 + 8) * 2

let result = power4 ((3 + 8)*2) 

Поскольку в Haskell значения оцениваются до тех пор, пока они не нужны, означает ли это, что x будет оцениваться четыре раза? Если да, то есть ли способ улучшить компилятор Haskell?

Спасибо.

Ответы [ 2 ]

10 голосов
/ 11 октября 2011

Нет, оно будет оцениваться только один раз. В вызове по имени он будет оценен четыре раза, но все реализации Haskell вызывают по необходимости (хотя стандарт не требует этого), что означает, что каждое выражение будет оцениваться максимум один раз.

Это применимо только тогда, когда выражение полностью конкретное. Например. нет гарантии, что в:

foo x = x + (1+2)

bar = foo 3 + foo 4

То, что при вычислении bar, (1+2) будет оцениваться только один раз. Фактически, он, вероятно, будет оценен дважды (если скомпилирован без оптимизации).

9 голосов
/ 11 октября 2011

Если вы не уверены, вы можете использовать trace для проверки (ref: http://www.haskell.org/haskellwiki/Debugging):

import Debug.Trace

power4 x = x*x*x*x

main = print $ power4 (trace "called" ((3+8)*2))

результат:

called
234256

поэтому выражение вычисляется только один раз.

...