2013-03-01 2 views
0

Если у меня есть функция вроде следующегоHaskell: Вызов функции несколько раз в одной и той же линии

f x = if g x /= Nothing then g x else False 

будет g называться дважды f или делает «кэш» Haskell результат g x после первой инстанции для возможного последующего использования в одной строке? Я пытаюсь оптимизировать некоторый код, и я не знаю, являются ли функции в стиле выше, чем в два раза дороже вычислительных затрат, чем я хочу.

Заранее спасибо.

+0

Кроме того, неважно, происходят ли вещи в одной строке. Это влияет на синтаксис, т. Е. Где начинается и заканчивается блок (который вы всегда можете писать явно с помощью '{}'), но кроме этого он ничего не влияет. – luqui

ответ

14

Реализации Haskell не запоминают вызовы функций.

Компиляторы Haskell, такие как GHC do do common subexpression eliminiation, но существуют ограничения.

Если у вас есть сомнения, разделите результат.

f x = if g' /= Nothing then g' else False 
    where g' = g x 

Но у вас есть ошибка типа, так как g 'не может быть и логическим, и возможно.

Но лучше записать так:

f x = case g x of 
      Nothing -> .. 
      Just _ -> .. 

вычислить и разделить результат только одной отрасли.

+0

Спасибо. Это прекрасно объясняет ситуацию. И да, я немного поспешил вписать эту функцию. – Robincognito

+1

Откуда вы знаете, что 'g'' не может быть и логическим, и« возможно »? Например, 'g' может быть' read', а исходная функция будет typecheck ... – kosmikus

+4

Хорошо, это могут быть экземпляры перегруженного 'g' :). Но '\ f g x -> если g x/= Nothing, то g x else False' не будет летать. –

Смежные вопросы