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 -O
и ghc -O2
, строка печатается только один раз. Это всегда первое, что нужно проверить, когда у вас есть проблемы с производительностью при использовании GHC:)
(By the путь, "отладка".Трейс!--12--> позволяет проверить эти виды вещей без необходимости писать руководство unsafePerformIO
писаки.)