Skip to content

Instantly share code, notes, and snippets.

@quantumman
Forked from mikeplus64/Marshal.hs
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quantumman/9926087 to your computer and use it in GitHub Desktop.
Save quantumman/9926087 to your computer and use it in GitHub Desktop.
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Marshal where
import Control.Applicative
import Control.Exception (bracket)
import Foreign
import Foreign.C
import GHC.Exts (RealWorld, unsafeCoerce#)
import GHC.IO (IO(..))
import System.IO.Unsafe
class Marshal a where
type Haskell a
toHaskell :: a -> IO (Haskell a)
fromHaskell :: Haskell a -> IO a
withHaskell :: Haskell a -> (a -> IO b) -> IO b
withHaskell x f = bracket (fromHaskell x) cleanup f
cleanup :: a -> IO ()
cleanup _ = return ()
instance Marshal CInt where
type Haskell CInt = Int
toHaskell = return . fromIntegral
fromHaskell = return . fromIntegral
instance Marshal CString where
type Haskell CString = String
toHaskell = peekCString
fromHaskell = newCString
withHaskell = withCString
cleanup = free
type family MarshalEach f where
MarshalEach (a -> b) = Haskell a -> MarshalEach b
MarshalEach (IO b) = IO (Haskell b)
class Marshals f where
marshals' :: f -> IO (MarshalEach f)
instance (Marshal a, Marshals b) => Marshals (a -> b) where
{-# INLINE marshals' #-}
marshals' f = return $!
\x -> unsafePerformIO (withHaskell x $ \y -> marshals' $ f y)
instance Marshal a => Marshals (IO a) where
{-# INLINE marshals' #-}
marshals' f = return $ toHaskell =<< f
marshals :: Marshals f => f -> IO (MarshalEach f)
marshals f = marshals' f
foreign import ccall puts :: CString -> IO CInt
main :: IO ()
main = do
nicePuts <- marshals puts
nicePuts "hello"
nicePuts "world"
return ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment