
2008/6/6 Galchin, Vasili
I want to do an incremental "experiment". I want just want to pass a C function to "callback" to a Haskell function. ???
This is easy; just declare the function via the FFI; here's an example from my implementation for the 2006 ICFP contest (http://www.boundvariable.org/); this interface is used to get access to a fast C VM from the high-level haskell debugger. The C VM can call back into Haskell in order to get and fetch characters from the console, and to notify the debugger of allocations and frees. The haskell-side debugger can query the state of the VM via the "get" functions exported by the VM. In this example, get_program_size is a first class haskell IO action; it can be passed around like any other action. If you know the function call is referentially transparent (pure), you can leave the "IO" off of the return result of the function; be careful with this, it's calling into whatever C-code you are giving and so you should treat it as carefully as you treat unsafePerformIO. The "unsafe" keyword allows GHC to optimize certain calls; in order to use it you need to know that the function won't call back into Haskell code. foreign import ccall unsafe load_program :: Ptr Word32 -> Word32 -> IO () foreign import ccall execute :: Word32 {-numCycles-} -> FunPtr GetChar -> FunPtr PutChar -> FunPtr Notify {-alloc-} -> FunPtr Notify {-free-} -> IO Word32 {-returnCode 0=success, 1=failure-} foreign import ccall unsafe get_program :: IO (Ptr Word32) foreign import ccall unsafe get_program_size :: IO Word32 foreign import ccall unsafe get_registers :: Ptr Word32 foreign import ccall unsafe get_pc :: IO Word32 foreign import ccall unsafe get_prev_pc :: IO Word32 foreign import ccall unsafe set_pc :: Word32 -> IO Bool type GetChar = IO Word32 type PutChar = Word32 -> IO () type Notify = Ptr Word32 -> Word32 -> IO () foreign import ccall "wrapper" mkGetChar :: GetChar -> IO (FunPtr GetChar) foreign import ccall "wrapper" mkPutChar :: PutChar -> IO (FunPtr PutChar) foreign import ccall "wrapper" mkNotify :: Notify -> IO (FunPtr Notify)