Mam funkcję (*~)
. Większość kosztów oceny x *~ y
pochodzi z inspekcji drugi argument, z grubsza wzdłuż tych linii:Częściowa ocena praworęcznych sekcji operatorów
(*~) :: a -> b d -> c d a
x *~ y = case y' of
Bar -> cheapFunction y' x
Baz -> cheapFunction2 y' x
Quux -> cheapFunction3 y' x
where
y' = expensive y
Czy istnieje jakiś sposób, aby przekonać GHC częściowo ocenić odcinki operatora jak (*~ y)
?
Próbowałem przepisanie go tak:
(*~) = flip go
where
go y = let y' = expensive y
in case y' of
Bar -> cheapFunction y'
Baz -> cheapFunction2 y'
Quux -> cheapFunction3 y'
ale nie wydaje się, aby pomóc. Myślę, że może to być spowodowane tym, że flip
wymaga wszystkich swoich argumentów przed wykonaniem przerzucania?
Jednym ze sposobów jest po prostu przerzucenie operatora, ale czyta się o wiele bardziej naturalnie, gdy kosztowny operand znajduje się po prawej stronie, ponieważ jest wyrównany z istniejącą notacją.
Czy mogę odpowiednio wypróbować {-# RULE #-}
? Jeśli tak, co powinna ona powiedzieć? (Nie jestem pewien, jak daleko składnia będzie wyglądała, zanim reguły będą szukać dopasowań, między innymi).
Nie jestem pewien, co częściowa ocena by kupić. 'y'' będzie już udostępnione. Czy chcesz dokonać przypomnienia? Musisz samodzielnie dodać pamięć. Jaką regułę chciałbyś napisać? –
Co stanie się, jeśli użyjesz niestandardowego 'flipa '? 'flip 'f x = \ y -> wbudowany f y x' – dfeuer
@ReinHenrichs Czy' y'' będzie już udostępniony? Jeśli tak, to moje zrozumienie jest dość zepsute i chciałbym przyjąć odpowiedź wyjaśniającą, w jaki sposób. Jeśli zrobię 'fmap (* ~ y) someLongList', czy nie będzie to za każdym razem przeliczone? –