C2HS marshalling double pointer - haskell

When there is a function like:
some_type_t* some_type_create(const char* name, char** errptr);
is there a way to get C2HS to generate a Haskell binding with the following signature?
someTypeCreate :: String -> IO (SomeTypeFPtr, String)
Here is what I can get so far:
{#fun some_type_create as ^
{`String', alloca- `Ptr CChar' peek*} -> `SomeTypeFPtr' #}
and it works in a way that I get
someTypeCreate :: String -> IO (SomeTypeFPtr, (Ptr CChar))
but how do I make it return IO (SomeTypeFPtr, String)
(or better IO (Either String SomeTypeFPtr)) since String represents the error)?
I assume that I should use/write a different marshaller to use instead of peek which would convert the result type but I don't quite understand how to do it.

I think I've figured it out, I just wrote the following marshallers:
nullableM :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
nullableM f ptr = if ptr == nullPtr
then return Nothing
else liftM Just $ f ptr
{-# INLINE nullableM #-}
toStringMaybe :: CString -> IO (Maybe String)
toStringMaybe = nullableM peekCString
{-# INLINE toStringMaybe #-}
peekStringMaybe :: Ptr CString -> IO (Maybe String)
peekStringMaybe x = peek x >>= toStringMaybe
{-# INLINE peekStringMaybe #-}

Related

How to update parts of the state in a State monad?

I have a type that I'd like to use as part of a state monad:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data SomeState = SomeState
{ _int :: Int,
_string :: String }
makeLenses ''SomeState
I have functions that operate on parts of the state in SomeState. Let's say they also use a state monad:
updateInt :: Int -> State Int ()
updateString :: String -> State String ()
On the top-level I have a functions that deal with the whole SomeState.
updateSomeState :: Int -> State SomeState ()
I would like to call updateInt and updateString as part of updateSomeState. I have the feeling it should be possible to "convert" the SomeState state monad into a state monad for one of its parts using lense, but I fail to see how.
Any help is appreciated.
I believe that you can do this with the zoom combinator from Control.Lens.Zoom:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
import Control.Monad.State
data SomeState = SomeState { _int :: Int, _string :: String } deriving (Show)
makeLenses ''SomeState
updateInt :: Int -> State Int ()
updateInt x = id .= x
updateString :: String -> State String ()
updateString x = id .= x
updateSomeState :: Int -> State SomeState ()
updateSomeState x = zoom int (updateInt x)
GHCi:
*Main> runStateT (updateSomeState 5) (SomeState 3 "hi")
Identity ((),SomeState {_int = 5, _string = "hi"})

How to convert list to JSVal?

I'm trying to build JS FFI for some JS library to get it work with GHCJS and I need to convert list to single JSVal
listToJSVal :: PToJSVal a => [a] -> JSVal
listToJSVal = map pToJSVal
but get error
Couldn't match type ‘[JSVal]’ with ‘JSVal’
Expected type: [a] -> JSVal
Actual type: [a] -> [JSVal]
obviously, I need concat function, but using mconcat gives
Could not deduce (Monoid JSVal) arising from a use of ‘mconcat’
from the context (PToJSVal a)
bound by the type signature for
Maybe, there is easier way how to do this conversion properly?
Also you could convert it at hand:
{-# LANGUAGE QuasiQuotes #-}
import GHCJS.Marshal.Pure
import GHCJS.Types
import GHCJS.Foreign.QQ
import GHCJS.Prim
listToJSVal :: PToJSVal a => [a] -> JSVal
listToJSVal xs = foldl push ar xs
where ar = [js'| [] |]
push as x = [js'| { `as.push(`x); $r = `as } |]
printArray :: JSVal -> IO ()
printArray as = [js_| for(i = 0;i < `as.length;i++) { console.log(`as[i]) } |]
main = do
printArray $ listToJSVal ([1,2,3,4,5]::[Int])
It appears that pToJSVal is only defined for base types.
For conversion of arbitrary values to JS, I would try the toJSVal and toJSValListOf functions defined in GHCJS/Marshal/Internal.hs (link)

Function with type synonym

Sorry for asking as potentially silly question, but returning to Haskell to do some conversion from one database package to a different one, I find myself a bit puzzled about how to do this properly.
In the Database.SQLite3 module, there is an execWithCallback with type
execWithCallback :: Database -> Text -> ExecCallback -> IO ()
Now, the callback is defined as
type ExecCallback = ColumnCount -> [Text]-> [Maybe Text] -> IO ()
that is, a function with type ExecCallback
My silly test code compiles and runs correctly:
{-# LANGUAGE OverloadedStrings #-}
import Database.SQLite3
import Data.Text
cb :: ColumnCount -> [Text] -> [Maybe Text] -> IO ()
cb n cnl ct = do print $ cnl !! 1
return ()
main = do
dh <- open "fileinfo.sqlite"
execWithCallback dh "select * from files;" cb
close dh
but then, what is the point of the type??? And, how do I specify that cb is an ExecCallback??
In Haskell, with type you define a type synonym. In your example that means that ExecCallback is just an alias for the type ColumnCount -> [Text]-> [Maybe Text] -> IO (), they are interchangeable.
You could change the following lines
cb :: ColumnCount -> [Text] -> [Maybe Text] -> IO ()
cb n cnl ct = do print $ cnl !! 1
return ()
to
cb :: ExecCallback
cb n cnl ct = do print $ cnl !! 1
return ()
and everything would still work as is. It can make your code shorter and more readable.
One other good example is
type String = [Char]
in Prelude. I bet you normally use String instead of [Char] in most cases. But you're absolutely free to use either.
Another (completely unrelated) example is the conduit package where some type synonyms make a major difference:
type Sink i = ConduitM i Void
type Consumer i m r = forall o. ConduitM i o m r
For something that's a sink for values of any type i, Sink i seems way more readable than ConduitM i Void. Same for Consumer.

Haskell LLVM binding Ambiguous Type

I am trying to get started with the LLVM binding for Haskell. A great place to start is Hello World.
The following is from a blog by the author of the binding.
bldGreet :: CodeGenModule (Function (IO ()))
bldGreet = do
puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32)
greetz <- createStringNul "Hello, World!"
func <- createFunction ExternalLinkage $ do
tmp <- getElementPtr greetz (0::Word32, (0::Word32, ()))
call puts tmp -- Throw away return value.
ret ()
return func
It does not compile.
Instead I get "Ambiguous type variable n0' in the constraint:
(type-level-0.2.4:Data.TypeLevel.Num.Sets.NatI n0)
arising from a use ofgetElementPtr0'
Probable fix: add a type signature that fixes these type variable(s)"
Here is a variation that does work
llvmModule :: TFunction (IO Word32)
llvmModule =
withStringNul "Hello world!" $ \s -> do
puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32)
main <- newNamedFunction ExternalLinkage "main" :: TFunction (IO Word32)
defineFunction main $ do
tmp <- getElementPtr0 s (0::Word32, ())
_ <- call puts tmp
ret (0::Word32)
return main
The first seems more natural. The question I have is what is the ambiguity in the first, and how do I fix it. The second question I have is why is the second not ambiguous.
Okay. So I solved the problem. It is indeed a typeclass thing. And it has only confused me more. However, I do have an answer to the solution. But do feel free to help my understanding out. First, some digging. The function createStringNul has type
createString :: String -> TGlobal (Array n Word8)
Fine. The problem the compiler was having is that the "n" in the Array type is ambiguous. It could literally be anything in the world. Lookup, Array, and you see
newtype Array n a
Now it is not so obvious, but upon a little digging, in particular wrt the call to getElementPtr, one finds that the n, really should be a Nat n, which is a type-level way to fix the size of the array. Now, the definition of Array n a, does not actually care it is really just a type synonym for [a]. So you can use D0, or D9 or whatever you want from the
Data.TypeLevel.Num.Reps
package. Fixing the size of the array, while a good idea was not actually taken into consideration by this function. But anyways, changing
greetz <- createStringNul "Hello, World!"
to
greetz <- createStringNul "Hello, World!" :: TGlobal (Array D0 Word8)
works.
Here is the interesting part... I did not expect it to work. D0 is supposed to be 0, so I did not understand why it was allowing me to store so many characters in a 0 size "Array" However, if you look at the source code, it is immediately clear that the type restriction is not actually payed attention to.
Fine, whatever, upon compiling one realizes that the createStringNul is deprecated, and withStringNul is preferred instead. Except I don't completely understand how withStringNul's types work.
createStringNul is marked as deprecated in the current version of llvm (3.0.1.0). Use withStringNul:
import Data.Word
import LLVM.Core
bldGreet :: CodeGenModule (Function (IO ()))
bldGreet = do
puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32)
func <- withStringNul "Hello, World!" $ \greetz ->
createFunction ExternalLinkage $ do
tmp <- getElementPtr greetz (0::Word32, (0::Word32, ()))
_ <- call puts tmp -- Throw away return value.
ret ()
return func
As to what causes the error in the first example, it's related to the fact that withStringNul has a more informative type: withStringNul :: String -> (forall n . Nat n => Global (Array n Word8) -> a) -> a -- cf. to createStringNul :: String -> TGlobal (Array n Word8). The function argument of withStringNul has a higher-rank type - it means that the function works for all n where n is a natural number.
If you really want to use createStringNul, you can make the first example compile by adding an explicit type signature for greetz:
{-# LANGUAGE TypeOperators #-}
module Test
where
import Data.Word
import Data.TypeLevel.Num.Reps
import LLVM.Core
bldGreet :: CodeGenModule (Function (IO ()))
bldGreet = do
puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32)
greetz <- createStringNul "Hello, World!"
func <- createFunction ExternalLinkage $ do
tmp <- getElementPtr (greetz :: Global (Array (D1 :* D3) Word8)) (0::Word32, (0::Word32, ()))
call puts tmp -- Throw away return value.
ret ()
return func
The :* type constructor comes from the type-level package and is used to construct type-level numbers. D1 :* D3 means that the array has size 13.

FFI Haskell Callback with State

My question is about how to write friendly Haskell Interfaces that model callbacks which can be invoked from C code. Callbacks are addressed here (HaskellWiki), however, I believe this question is more complex than the example from that link.
Suppose we have C code, requiring callbacks and the header looks like the following:
typedef int CallbackType(char* input, char* output, int outputMaxSize, void* userData)
int execution(CallbackType* caller);
In this case the function execution takes a callback function and will use that to process new data, essentially a closure. The call back expects an input string, an output buffer which has been allocated with size outputMaxSize and the userData pointer, which can be casted however inside the callback.
We do similar things in haskell, when we pass around closures with MVars, so we can still communicate. Therefore when we write the Foreign interface, we'd like to keep this sort of type.
Specifically here is what the FFI Code might look like:
type Callback = CString -> CString -> CInt -> Ptr () -> IO CInt
foreign import ccall safe "wrapper"
wrap_callBack :: Callback -> IO (FunPtr Callback)
foreign import ccall safe "execution"
execute :: FunPtr Callback -> IO CInt
Users should be able to do this sort of thing, but it feels like a poor interface since
they need to write callbacks with type Ptr (). Rather we'd like to replace this with MVars
which feel more natural. So we'd like to write a function:
myCallback :: String -> Int -> MVar a -> (Int, String)
myCallback input maxOutLength data = ...
In order to convert to C, we'd like to have a function like:
castCallback :: ( String -> Int -> MVar a -> (Int, String) )
-> ( CString -> CString -> CInt -> Ptr () -> IO CInt )
main = wrap_callBack (castCallback myCallback) >>= execute
In this case castCallback is for the most part not hard to implement,
convert string -> cstring, Int -> CInt, and copy over the output string.
The hard part however is resolving the MVar to Ptr, which is not necessarily storable.
My Question is what is the best way to go about writing callback code in Haskell, which can still be communicated with.
If you want to access a Haskell structure like MVar which doesn't have a library function to convert it to a pointer representation (meaning it is not supposed to be passed to C), then you need to do partial function application.
In the partial function application, the trick is to build a partial function with MVar already applied, and pass the pointer to that function to C. C will then call it back with the object to put in MVar. An example code below (all the code below is derived from something I did before - I modified it for examples here but haven't tested the modifications):
-- this is the function that C will call back
syncWithC :: MVar CInt -> CInt -> IO ()
syncWithC m x = do
putMVar m x
return ()
foreign import ccall "wrapper"
syncWithCWrap :: (CInt -> IO ()) -> IO (FunPtr (CInt -> IO ()))
main = do
m <- newEmptyMVar
-- create a partial function with mvar m already applied. Pass to C. C will back with CInt
f <- syncWithCWrap $ syncWithC m
What if your MVar object is more complex? Then you need to build a Storable instance of the MVar object if it doesn't exist. For example, if I want to use an MVar with array of pair of Ints, then first define a Storable instance of Int pairs (SV is Storable Vector, MSV is Storable Mutable Vector):
data VCInt2 = IV2 {-# UNPACK #-} !CInt
{-# UNPACK #-} !CInt
instance SV.Storable VCInt2 where
sizeOf _ = sizeOf (undefined :: CInt) * 2
alignment _ = alignment (undefined :: CInt)
peek p = do
a <- peekElemOff q 0
b <- peekElemOff q 1
return (IV2 a b)
where q = castPtr p
{-# INLINE peek #-}
poke p (IV2 a b) = do
pokeElemOff q 0 a
pokeElemOff q 1 b
where q = castPtr p
{-# INLINE poke #-}
Now, you can just pass a pointer to the vector to C, have it update the vector, and call back the void function with no arguments (since C is already filling the vector). This also avoid expensive data marshalling by sharing memory between Haskell and C.
-- a "wrapper" import is a converter for converting a Haskell function to a foreign function pointer
foreign import ccall "wrapper"
syncWithCWrap :: IO () -> IO (FunPtr (IO ()))
-- call syncWithCWrap on syncWithC with both arguments applied
-- the result is a function with no arguments. Pass the function, and
-- pointer to x to C. Have C fill in x first, and then call back syncWithC
-- with no arguments
syncWithC :: MVar (SV.Vector VCInt2) -> MSV.IOVector VCInt2 -> IO ()
syncWithC m1 x = do
SV.unsafeFreeze x >>= putMVar m1
return ()
On C side, you will need a struct declaration for VCInt2 so that it knows how to parse it:
/** Haskell Storable Vector element with two int members **/
typedef struct vcint2{
int a;
int b;
} vcint2;
So, on C side, you are passing it vcint2 pointer for MVar object.

Resources