The `_ccall_' construct is part of the `IO' monad because 9 out of 10 uses will be to call imperative functions with side effects such as `printf'. Use of the monad ensures that these operations happen in a predictable order in spite of laziness and compiler optimisations.
To avoid having to be in the monad to call a C function, it is possible to use `unsafePerformIO', which is available from the `IOExts' module. There are three situations where one might like to call a C function from outside the IO world:
atan2d :: Double -> Double -> Double atan2d y x = unsafePerformIO (_ccall_ atan2d y x) sincosd :: Double -> (Double, Double) sincosd x = unsafePerformIO $ do da <- newDoubleArray (0, 1) _casm_ "sincosd( %0, &((double *)%1[0]), &((double *)%1[1]) );" x da s <- readDoubleArray da 0 c <- readDoubleArray da 1 return (s, c)
empty :: EFS x update :: EFS x -> Int -> x -> EFS x lookup :: EFS a -> Int -> a empty = unsafePerformIO (_ccall_ emptyEFS) update a i x = unsafePerformIO $ makeStablePtr x >>= \ stable_x -> _ccall_ updateEFS a i stable_x lookup a i = unsafePerformIO $ _ccall_ lookupEFS a i >>= \ stable_x -> deRefStablePtr stable_xYou will almost always want to use `ForeignObj's with this.
trace :: String -> a -> a trace string expr = unsafePerformIO ( ((_ccall_ PreTraceHook sTDERR{-msg-}):: IO ()) >> fputs sTDERR string >> ((_ccall_ PostTraceHook sTDERR{-msg-}):: IO ()) >> return expr ) where sTDERR = ("stderr" :: Addr)(This kind of use is not highly recommended -- it is only really useful in debugging code.)