Re: [Haskell] How to make sure that a function is evaluated only once?
Thanks to all who replied. I still haven't figured out a solution. I thought about memoizing the result, as several of you have suggested, but I am scared by the huge argument space. Lemmih <lemmih@gmail.com> wrote:
Do you have a minimal test case showing the undesirable behaviour?
gf (actCnt,sndCnt, sizex, sizey, locx, locy) iPack = (newSndCnt sndCnt outPack, outPack) where outPack = fWrapper sizex sizey locx locy actCnt iPack newSndCnt n (Abst,_) = n newSndCnt n (Prst _,_) = n + 1 This is a simplified context for the call to the C function, which is wrapped by fWrapper. I figured out that one reason for double evaluation is that outPack is used twice in the return expression of gf. So my question now is, can I force the evaluation machine to evaluate fWrapper once and use the same result value in both places where outPack is used? I tried the NOINLINE pragma both on outPack and on fWrapper, but to no avail. Again, I am grateful for any hint to a work-around. Cheers, Axel
On 12/21/06, Axel Jantsch <axel@kth.se> wrote:
Hello,
I have a function with type
f :: Int -> Int -> Int -> Int -> Int -> NRup -> NRdown
and I want to make sure it is evaluated only once for the same set of arguments but I observe that it is always evaluated several times.
f is implemented in C and called via the FFI. The C function may or may not be pure. In principle it is but it is convenient to keep some state for debugging and monitoring. Anyway, even if it is pure, I want it to evaluate only once for a set of arguments because of performance.
How can I enforce this? Is there a GHC option for that? Is there a way to write the Haskell code to achieve this?
I have asked the same question in the context of FFI, but now it seems to me this question is not directly related to the FFI.
Haskell implementations are free to evaluate expressions as many times as they feel like. If you want to be absolutely sure, use the IO monad. On the other hand, you might get the same effect with a few cleverly placed {-# NOINLINE #-} pragmas. Do you have a minimal test case showing the undesirable behaviour?
-- Cheers, Lemmih _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
-- Phone: +46 8 790 4124, Email: axel@kth.se, Web: www.it.kth.se/~axel
On 12/22/06, Axel Jantsch <axel@kth.se> wrote:
Thanks to all who replied. I still haven't figured out a solution. I thought about memoizing the result, as several of you have suggested, but I am scared by the huge argument space.
Lemmih <lemmih@gmail.com> wrote:
Do you have a minimal test case showing the undesirable behaviour?
gf (actCnt,sndCnt, sizex, sizey, locx, locy) iPack = (newSndCnt sndCnt outPack, outPack) where outPack = fWrapper sizex sizey locx locy actCnt iPack newSndCnt n (Abst,_) = n newSndCnt n (Prst _,_) = n + 1
This is a simplified context for the call to the C function, which is wrapped by fWrapper. I figured out that one reason for double evaluation is that outPack is used twice in the return expression of gf.
So my question now is, can I force the evaluation machine to evaluate fWrapper once and use the same result value in both places where outPack is used?
I tried the NOINLINE pragma both on outPack and on fWrapper, but to no avail.
Again, I am grateful for any hint to a work-around.
Try using a let-expression and/or make the tuple arguments strict. -- Cheers, Lemmih
I thought a let expression was just as lazy as a where clause. Is this not true? Dan Lemmih wrote:
On 12/22/06, Axel Jantsch <axel@kth.se> wrote:
Thanks to all who replied. I still haven't figured out a solution. I thought about memoizing the result, as several of you have suggested, but I am scared by the huge argument space.
Lemmih <lemmih@gmail.com> wrote:
Do you have a minimal test case showing the undesirable behaviour?
gf (actCnt,sndCnt, sizex, sizey, locx, locy) iPack = (newSndCnt sndCnt outPack, outPack) where outPack = fWrapper sizex sizey locx locy actCnt iPack newSndCnt n (Abst,_) = n newSndCnt n (Prst _,_) = n + 1
This is a simplified context for the call to the C function, which is wrapped by fWrapper. I figured out that one reason for double evaluation is that outPack is used twice in the return expression of gf.
So my question now is, can I force the evaluation machine to evaluate fWrapper once and use the same result value in both places where outPack is used?
I tried the NOINLINE pragma both on outPack and on fWrapper, but to no avail.
Again, I am grateful for any hint to a work-around.
Try using a let-expression and/or make the tuple arguments strict.
participants (3)
-
Axel Jantsch -
Dan Weston -
Lemmih