Force single evaluation?

Axel Jantsch axel at kth.se
Wed Dec 20 10:10:00 EST 2006



I tried both alternatives:

foreign import ccall originalFn :: Arg1T -> Arg2T -> IO ResultT

foreign import ccall originalFn :: Arg1T -> Arg2T -> ResultT


but in both cases the C function originalFn is called several times for
the same arguments. And it is bound only in one place.

I don't understand why.
Maybe the problem is that the data marshaling has to be done within the
monad?

My simplified codes is as follows:

f :: InparT -> IO CInt
f inPar = do
          inP <- malloc
          poke inP inPar

          r <- cfun inP 

          free inP
          return r

foreign import ccall "cfun" :: Ptr InparT -> IO CInt

So even if I make cfun pure (which it is), the enclosing function f is
not. 

Shall I pretend f is pure and wrap it into unsafePerformIO? 

Regards,
Axel

Malcolm Wallace <Malcolm.Wallace at cs.york.ac.uk> wrote:

> "Axel Jantsch" <axel at kth.se> wrote:
> 
> > I call a C function from a Haskell program. I am using unsafePerformIO
> > to use it outside a monad. 
> > 
> > Even though the C function does not have any side effect, I absolutely
> > don't want to evaluate it more than once for performance reasons. But
> > my impression is that it is evaluated several times.
> > 
> > 1. Can I monitor somehow how often it is evaluated?
> 
> You could wrap it (in C) with another function that keeps a counter of
> invocations in a static local variable.
> 
>     result_t  originalFn (arg1_t arg1, arg2_t arg2);
>     result_t  wrappedFn  (arg1_t arg1, arg2_t arg2) {
>       static int i = 0;
>       i++;
>       fprintf(stderr,"originalFn called %d times\n",i);
>       return originalFn(arg1,arg2);
>     }
> 
> > 2. Can I ensure that the function is evaluated only once?
> 
> How about stating in the type of the FFI decl that the C function is
> pure (even if it is not)?  Then be sure to bind its result in only one
> place.  That should guarantee it is called only once.
> 
>     foreign import ccall originalFn :: Arg1T -> Arg2T -> IO ResultT
> becomes
>     foreign import ccall originalFn :: Arg1T -> Arg2T -> ResultT
> 
> Regards,
>     Malcolm
> _______________________________________________
> FFI mailing list
> FFI at haskell.org
> http://www.haskell.org/mailman/listinfo/ffi
> 

-- 
Phone: +46 8 790 4124, Email: axel at kth.se, Web: www.it.kth.se/~axel


More information about the FFI mailing list