У меня есть функция (*~)
. Большая часть стоимости оценки x *~ y
приходит досматривать второй аргумент, примерно вдоль этих линий:Частичная оценка правых секций оператора
(*~) :: 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
Есть ли какой-нибудь способ, чтобы убедить GHC частично оценить секции оператора, как (*~ y)
?
Я попытался переписать его как:
(*~) = flip go
where
go y = let y' = expensive y
in case y' of
Bar -> cheapFunction y'
Baz -> cheapFunction2 y'
Quux -> cheapFunction3 y'
но это не похоже, чтобы помочь. Я думаю, это может быть потому, что flip
требует всех аргументов, прежде чем он перевернет?
Один из способов - просто перевернуть сам оператор, но он читается гораздо более естественным образом, когда дорогой операнд находится справа, потому что он совпадает с существующей нотацией.
Может ли надлежащим образом обработано {-# RULE #-}
освободить меня сюда? Если да, то что сказать? (Я не знаю, как далеко синтаксис секционирования будет снят, прежде чем правила будут искать совпадения, среди прочего.)
Я не уверен, что частичная оценка вас купила. 'y'' уже будет использоваться. Вы хотите заметок? Вам нужно будет добавить memoization самостоятельно. Какое правило вы бы хотели написать? –
Что произойдет, если вы используете пользовательский 'flip'? 'flip 'f x = \ y -> inline f y x' – dfeuer
@ReinHenrichs Будет ли' '' уже использоваться? Если так, то мое понимание довольно сломанно, и я хотел бы принять ответ, объясняющий, как это сделать. Если я делаю 'fmap (* ~ y) someLongList', он не будет пересматриваться каждый раз? –