ViewPatterns и несколько вызовов в Haskell

Я читаю этот:

http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns

мне нравится идея, хочу использовать расширение. Однако я хотел бы убедиться в одном: оценивается ли функция view один раз для одного сопоставления.

Итак, предположим, у нас есть:

{-# LANGUAGE ViewPatterns #-}
...

f (view -> Nothing) = ...
f (view -> Just x) = ...

view :: a -> Maybe b

теперь предположим, что я призываю f a. Is view вызывается дважды или только один раз для заданного аргумента a?

редактировать:

Я попытался выяснить, так ли это и написал следующее:

{-# LANGUAGE ViewPatterns #-}

import System.IO.Unsafe

blah (ble -> Nothing) = 123
blah (ble -> Just x) = x

ble x = unsafePerformIO $ do
    putStrLn $ "Inside ble: " ++ show x
    return x

main :: IO ()
main = do
    putStrLn $ "Main: " ++ show (blah $ Just 234)

вывод с помощью GHC:

Inside ble: Just 234
Inside ble: Just 234
Main: 234

вывод с использованием GHC (с оптимизацией)

Inside ble: Just 234
Main: 234

вывод с помощью GHCi:

Main: Inside ble: Just 234
Inside ble: Just 234
234

1 ответов


только один раз:

эффективность: когда такая же функция взгляда приложена внутри несколько веток определения функции или выражения (например,, в size выше), GHC делает попытку собрать эти приложения в одно вложенное выражение case, так что представление функция применяется только один раз. Компиляция картины в GHC следует за матричный алгоритм, описанный в главе 4 в Реализация функциональных языков программирования. Когда этот строки первого столбца матрицы всех моделей с "такое же" выражение, эти шаблоны преобразуются в одно вложенное случай. Это включает, например, смежные шаблоны представления, которые выстраиваются в линию в кортеж, как в

f ((view -> A, p1), p2) = e1
f ((view -> B, p3), p4) = e2

текущее понятие, когда два выражения шаблона представления являются " то же самое " очень ограничено: это даже не полное синтаксическое равенство. Однако он включает переменные, литералы, приложения и кортежи; например, два экземпляра view ("hi", "there") будет собранный. Однако текущая реализация не сопоставима с Альфа-эквивалентность, поэтому два экземпляра (x, view x -> y) не будут объединены.

- руководство GHC

что касается вашего фрагмента, проблема в том, что ты не компиляция с оптимизацией; с ghc -O и ghc -O2, строка печатается только один раз. Это всегда первое, что нужно проверить, когда у вас есть проблемы с производительностью при использовании GHC:)

(By the путь, "отладка".Трейс!--12--> позволяет проверить эти виды вещей без необходимости писать руководство unsafePerformIO писаки.)