2012-01-20 21 views
11

czytam to:ViewPatterns i wiele połączeń w Haskell

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

podoba mi się pomysł, chcesz używać rozszerzenia. Chciałbym jednak upewnić się co do jednego: czy funkcja widoku jest oceniana raz dla pojedynczego dopasowania.

Więc powiedzmy mamy:

Teraz powiedzmy modlę f a. Czy jest view wywoływana dwukrotnie lub tylko raz dla danego argumentu a?

EDIT:

Próbowałem dowiedzieć się, czy jest to przypadek i napisał następujący:

{-# 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) 

Output korzystając GHC:

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

wyjścia używając GHC (z optymalizacja)

Inside ble: Just 234 
Main: 234 

wyjścia używając GHCi:

Main: Inside ble: Just 234 
Inside ble: Just 234 
234 
+0

GHC ma specjalny hack, aby uniknąć ponownego obliczania identycznych wyrażeń widoku. – augustss

Odpowiedz

13

Tylko raz:

Wydajność: Kiedy ta sama funkcja widok jest stosowana w wielu gałęziach definicji funkcji lub przypadek ekspresji (np w size powyżej), GHC podejmuje próbę zebrania tych aplikacji w pojedynczym zagnieżdżonym wyrobie przypadku, tak aby funkcja widoku została zastosowana tylko raz. Kompilacja wzorów w GHC jest zgodna z algorytmem macierzowym opisanym w rozdziale 4 dokumentu The Implementation of Functional Programming Languages. Gdy górne rzędy pierwszej kolumny macierzy są wzorami widoków z "takim samym" wyrażeniem " ", wzory te są przekształcane w pojedynczą zagnieżdżoną obudowę . Dotyczy to, na przykład, sąsiadujące wzory pogląd, że line up w krotki, jak w

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

Obecne pojęcie kiedy dwa wyrażenia widok wzór są „ same” jest bardzo ograniczony: nie jest jeszcze pełny równość składniowa. Zawiera jednak zmienne, literały, aplikacje i krotki; , np. Dwa wystąpienia view ("hi", "there") zostaną zebrane . Jednak obecna implementacja nie porównuje do równoważności alfa do , więc dwa wystąpienia (x, view x -> y) nie zostaną połączone.

- The GHC manual

chodzi o fragmencie, problemem jest to, że nie jesteś kompilacji z optymalizacją; zarówno z ghc -O i ghc -O2, wiersz jest drukowany tylko raz.To zawsze pierwszą rzeczą, aby sprawdzić, kiedy masz problemy związane z wydajnością podczas korzystania GHC :)

(Nawiasem mówiąc, Debug.Trace pozwala sprawdzić te rodzaje rzeczy bez konieczności pisania ręcznego unsafePerformIO hacki.)

+0

Czy jest możliwe, że GHC wstawia dodatkowe oceny zapasowe z powodu performUnsafeIO? Nie martw się, użyłem go tylko do przetestowania funkcji. – julkiewicz

+0

Dodałem próbkę konkretnego kodu. – julkiewicz

+0

@julkiewicz: Zaktualizowałem swoją odpowiedź :) – ehird

Powiązane problemy