Ever wondered if something like inline assembly were possible in Haskell? Want to return multiple values from foreign code? Here’s an article experimenting with foreign import prim. It was originally written in Japanese several years ago, but I thought it might be interesting to the global community, so I revised and translated it. I hope you enjoy this article!
TBH I’m more interested in passing inline structs. Some C libs absolutely love that, forcing wrapper churn around them.
There’s good reason for it to be Ptr at the boundary. Maaaybe there’s an argument for extending the FFI to automate the pointers in and “out” pointers. But it’s super annoying to have to write cbits.
Being able to use multiline strings for this would be killer. In the way JSFFI works. Spitballing…
foreign import ccall unsafe
"""
*$3 = someFunc(*$1, $2);
"""
someFunc :: Ptr StructIn -> Int -> Ptr StructOut -> IO ()
I guess that’s not multiline, but imagine if you wanted to stuff more than one line in there. The positional arguments are on display though.
and then, like JSFFI, some C function is auto-generated
(Also if this actually already exists for C and i missed the memo, i’ll be ecstatic lol)
It exists for MicroHs. ![]()
It’s a little more cumbersome, because the pointers are void*, but they can be cast.
Oh yes the void* thing makes sense (how would the FFI even know the types?). But that’s still a step up!
Excited to try it on a MicroHs project - GHC’s gotta steal this!
You need to say value before the code snippet to get the $ expansion.
Regarding passing structs by value, hs-bindgen implements this by generating the wrapper function within the generated Haskell module, along with a Haskell translation that handles the memory allocation.
In this example, function thing_fun_1 is passed a struct argument by value and function thing_fun_2 returns a struct result by value. The generated code includes all the necessary C and Haskell code, only exporting the public API.