-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Python interpreter embedded into haskell. -- -- This package embeds python interpreter into haskell program and allows -- to write python snippets as quasiquotes. Values could be easily -- transferred between python and haskell. It's possible to call haskell -- from python as well. @package inline-python @version 0.1 -- | Data types and utilities. module Python.Inline.Types -- | Monad for code which is interacts with python interpreter. Only one -- haskell thread can interact with python interpreter at a time. -- Function that execute Py make sure that this invariant is -- held. Also note that all code in Py monad is executed with -- asynchronous exception masked, but liftIO removes mask. data Py a -- | Execute python action. It will take and hold global lock while code is -- executed. Python exceptions raised during execution are converted to -- haskell exception PyError. runPy :: Py a -> IO a -- | Inject IO into Py monad without changing masking -- state (unlike liftIO) pyIO :: IO a -> Py a -- | Some python object. Since almost everything in python is mutable it -- could only be accessed only in IO monad. data PyObject unsafeWithPyObject :: forall a. PyObject -> (Ptr PyObject -> Py a) -> Py a -- | Python exception converted to haskell. data PyError -- | Python exception. Contains exception type and message as strings. PyError :: !PyException -> PyError -- | It's not possible to convert given python value to a haskell value BadPyType :: PyError -- | Data type is suitable but value is outside of allowed range. For -- example attempting to convert 1000 to Word8 will result in -- this exception. OutOfRange :: PyError -- | Initialization of python interpreter failed PyInitializationFailed :: PyError -- | Python interpreter is not initialized PythonNotInitialized :: PyError -- | Python interpreter is not initialized PythonIsFinalized :: PyError -- | Python exception converted to haskell value data PyException PyException :: !String -> !String -> !PyObject -> PyException -- | Exception type as a string [$sel:ty:PyException] :: PyException -> !String -- | String representation of an exception [$sel:str:PyException] :: PyException -> !String -- | Exception object [$sel:exception:PyException] :: PyException -> !PyObject -- | Internal error. If this exception is thrown it means there's bug in a -- library. data PyInternalError PyInternalError :: String -> PyInternalError -- | Conversion between haskell data types and python values module Python.Inline.Literal -- | Convert python object to haskell value. class FromPy a -- | Convert python value into haskell value. This function should try to -- not modify python's data. This function should avoid throwing haskell -- exception. Any python exceptions should be thrown as PyError. -- When data type couldn't be converted BadPyType or -- OutOfRange should be thrown to indicate failure. -- -- This is low level function. It should be only used when working with -- python's C API. Otherwise fromPy is preferred. basicFromPy :: FromPy a => Ptr PyObject -> Py a -- | Convert haskell value to python value. class ToPy a -- | Convert haskell value to python object. This function returns strong -- reference to newly create objects (except singletons like -- None, True, etc). -- -- Implementations should try to avoid failing conversions. There're two -- ways of signalling failure: errors on python side should return NULL -- and raise python exception. Haskell code should just throw exception. -- -- This is low level function. It should be only used when working with -- python's C API. Otherwise toPy is preferred. basicToPy :: ToPy a => a -> Py (Ptr PyObject) -- | Old hack for handling of strings basicListToPy :: ToPy a => [a] -> Py (Ptr PyObject) -- | Convert haskell value to a python object. toPy :: ToPy a => a -> Py PyObject -- | Convert python object to haskell value. All python exceptions which -- happen during execution will be converted to PyError. fromPyEither :: FromPy a => PyObject -> Py (Either PyError a) -- | Convert python object to haskell value. Will return Nothing -- if BadPyType or OutOfRange is thrown. Other python -- exceptions are rethrown. fromPy :: FromPy a => PyObject -> Py (Maybe a) -- | Convert python object to haskell value. Throws exception on failure. fromPy' :: FromPy a => PyObject -> Py a instance Python.Inline.Literal.ToPy GHC.Int.Int64 instance Python.Inline.Literal.FromPy GHC.Int.Int64 instance Python.Inline.Literal.ToPy GHC.Word.Word64 instance Python.Inline.Literal.FromPy GHC.Word.Word64 instance Python.Inline.Literal.ToPy Foreign.C.Types.CInt instance Python.Inline.Literal.FromPy Foreign.C.Types.CInt instance Python.Inline.Literal.ToPy Foreign.C.Types.CUInt instance Python.Inline.Literal.FromPy Foreign.C.Types.CUInt instance Python.Inline.Literal.ToPy Foreign.C.Types.CShort instance Python.Inline.Literal.FromPy Foreign.C.Types.CShort instance Python.Inline.Literal.ToPy Foreign.C.Types.CUShort instance Python.Inline.Literal.FromPy Foreign.C.Types.CUShort instance Python.Inline.Literal.ToPy Foreign.C.Types.CChar instance Python.Inline.Literal.FromPy Foreign.C.Types.CChar instance Python.Inline.Literal.ToPy Foreign.C.Types.CUChar instance Python.Inline.Literal.FromPy Foreign.C.Types.CUChar instance Python.Inline.Literal.ToPy Foreign.C.Types.CSChar instance Python.Inline.Literal.FromPy Foreign.C.Types.CSChar instance Python.Inline.Literal.ToPy GHC.Types.Double instance Python.Inline.Literal.FromPy GHC.Types.Double instance Python.Inline.Literal.FromPy Python.Internal.Types.PyObject instance Python.Inline.Literal.FromPy Foreign.C.Types.CLong instance Python.Inline.Literal.FromPy Foreign.C.Types.CLLong instance Python.Inline.Literal.FromPy Foreign.C.Types.CULong instance Python.Inline.Literal.FromPy Foreign.C.Types.CULLong instance Python.Inline.Literal.FromPy Foreign.C.Types.CDouble instance Python.Inline.Literal.FromPy GHC.Types.Float instance Python.Inline.Literal.FromPy GHC.Types.Int instance Python.Inline.Literal.FromPy GHC.Types.Word instance Python.Inline.Literal.FromPy GHC.Int.Int8 instance Python.Inline.Literal.FromPy GHC.Int.Int16 instance Python.Inline.Literal.FromPy GHC.Int.Int32 instance Python.Inline.Literal.FromPy GHC.Word.Word8 instance Python.Inline.Literal.FromPy GHC.Word.Word16 instance Python.Inline.Literal.FromPy GHC.Word.Word32 instance Python.Inline.Literal.FromPy GHC.Types.Char instance Python.Inline.Literal.FromPy GHC.Types.Bool instance (Python.Inline.Literal.FromPy a, Python.Inline.Literal.FromPy b) => Python.Inline.Literal.FromPy (a, b) instance (Python.Inline.Literal.FromPy a, Python.Inline.Literal.FromPy b, Python.Inline.Literal.FromPy c) => Python.Inline.Literal.FromPy (a, b, c) instance (Python.Inline.Literal.FromPy a, Python.Inline.Literal.FromPy b, Python.Inline.Literal.FromPy c, Python.Inline.Literal.FromPy d) => Python.Inline.Literal.FromPy (a, b, c, d) instance Python.Inline.Literal.FromPy a => Python.Inline.Literal.FromPy [a] instance (Python.Inline.Literal.FromPy a, GHC.Classes.Ord a) => Python.Inline.Literal.FromPy (Data.Set.Internal.Set a) instance (Python.Inline.Literal.FromPy k, Python.Inline.Literal.FromPy v, GHC.Classes.Ord k) => Python.Inline.Literal.FromPy (Data.Map.Internal.Map k v) instance Python.Inline.Literal.FromPy a => Python.Inline.Literal.FromPy (Data.Vector.Vector a) instance (Python.Inline.Literal.FromPy a, Foreign.Storable.Storable a) => Python.Inline.Literal.FromPy (Data.Vector.Storable.Vector a) instance (Python.Inline.Literal.FromPy a, Data.Primitive.Types.Prim a) => Python.Inline.Literal.FromPy (Data.Vector.Primitive.Vector a) instance (Python.Inline.Literal.FromPy a, Data.Vector.Unboxed.Base.Unbox a) => Python.Inline.Literal.FromPy (Data.Vector.Unboxed.Base.Vector a) instance Python.Inline.Literal.FromPy a => Python.Inline.Literal.FromPy (Data.Vector.Strict.Vector a) instance (Python.Inline.Literal.FromPy a, GHC.Show.Show a, Python.Inline.Literal.ToPy b) => Python.Inline.Literal.ToPy (a -> GHC.Types.IO b) instance (Python.Inline.Literal.FromPy a1, Python.Inline.Literal.FromPy a2, Python.Inline.Literal.ToPy b) => Python.Inline.Literal.ToPy (a1 -> a2 -> GHC.Types.IO b) instance Python.Inline.Literal.ToPy Python.Internal.Types.PyObject instance Python.Inline.Literal.ToPy () instance Python.Inline.Literal.ToPy Foreign.C.Types.CLong instance Python.Inline.Literal.ToPy Foreign.C.Types.CLLong instance Python.Inline.Literal.ToPy Foreign.C.Types.CULong instance Python.Inline.Literal.ToPy Foreign.C.Types.CULLong instance Python.Inline.Literal.ToPy Foreign.C.Types.CDouble instance Python.Inline.Literal.ToPy GHC.Types.Float instance Python.Inline.Literal.ToPy GHC.Types.Int instance Python.Inline.Literal.ToPy GHC.Types.Word instance Python.Inline.Literal.ToPy GHC.Int.Int8 instance Python.Inline.Literal.ToPy GHC.Int.Int16 instance Python.Inline.Literal.ToPy GHC.Int.Int32 instance Python.Inline.Literal.ToPy GHC.Word.Word8 instance Python.Inline.Literal.ToPy GHC.Word.Word16 instance Python.Inline.Literal.ToPy GHC.Word.Word32 instance Python.Inline.Literal.ToPy GHC.Types.Char instance Python.Inline.Literal.ToPy GHC.Types.Bool instance (Python.Inline.Literal.ToPy a, Python.Inline.Literal.ToPy b) => Python.Inline.Literal.ToPy (a, b) instance (Python.Inline.Literal.ToPy a, Python.Inline.Literal.ToPy b, Python.Inline.Literal.ToPy c) => Python.Inline.Literal.ToPy (a, b, c) instance (Python.Inline.Literal.ToPy a, Python.Inline.Literal.ToPy b, Python.Inline.Literal.ToPy c, Python.Inline.Literal.ToPy d) => Python.Inline.Literal.ToPy (a, b, c, d) instance Python.Inline.Literal.ToPy a => Python.Inline.Literal.ToPy [a] instance (Python.Inline.Literal.ToPy a, GHC.Classes.Ord a) => Python.Inline.Literal.ToPy (Data.Set.Internal.Set a) instance (Python.Inline.Literal.ToPy k, Python.Inline.Literal.ToPy v, GHC.Classes.Ord k) => Python.Inline.Literal.ToPy (Data.Map.Internal.Map k v) instance Python.Inline.Literal.ToPy a => Python.Inline.Literal.ToPy (Data.Vector.Vector a) instance (Python.Inline.Literal.ToPy a, Foreign.Storable.Storable a) => Python.Inline.Literal.ToPy (Data.Vector.Storable.Vector a) instance (Python.Inline.Literal.ToPy a, Data.Primitive.Types.Prim a) => Python.Inline.Literal.ToPy (Data.Vector.Primitive.Vector a) instance (Python.Inline.Literal.ToPy a, Data.Vector.Unboxed.Base.Unbox a) => Python.Inline.Literal.ToPy (Data.Vector.Unboxed.Base.Vector a) instance Python.Inline.Literal.ToPy a => Python.Inline.Literal.ToPy (Data.Vector.Strict.Vector a) instance Python.Inline.Literal.ToPy b => Python.Inline.Literal.ToPy (GHC.Types.IO b) -- | Quasiquoters for embedding python expression into haskell programs. -- Python is statement oriented and heavily relies on mutable state. This -- means we need several different quasiquoters. -- --

Syntax in quasiquotes

-- -- Note on syntax. Python's grammar is indentation sensitive and -- quasiquote is passed to QuasiQuoter without any adjustment. So -- this seemingly reasonable code: -- --
--   foo = [py_| do_this()
--               do_that()
--             |]
--   
-- -- results in following source code. -- --
--   do_this()
--              do_that()
--   
-- -- There's no sensible way to adjust indentation, since we don't know -- original indentation of first line of quasiquote in haskell's code. -- Thus rule: First line of multiline quasiquote must be empty. -- This is correct way to write code: -- --
--   foo = [py_|
--           do_this()
--           do_that()
--           |]
--   
module Python.Inline.QQ -- | Evaluate sequence of python statements. It works in the same way as -- python's exec. All module imports and all variables defined -- in this quasiquote will be visible to later quotes. -- -- It creates value of type Py () pymain :: QuasiQuoter -- | Evaluate sequence of python statements. All module imports and all -- variables defined in this quasiquote will be discarded and won't be -- visible in later quotes. -- -- It creates value of type Py () py_ :: QuasiQuoter -- | Evaluate single python expression. It only accepts single expressions -- same as python's eval. -- -- This quote creates object of type Py PyObject pye :: QuasiQuoter -- | Another quasiquoter which works around that sequence of python -- statements doesn't have any value associated with it. Content of -- quasiquote is function body. So to get value out of it one must call -- return pyf :: QuasiQuoter -- | This library allows to embed as quasiquotes and execute arbitrary -- python code in haskell programs. Take for example following program: -- --
--   {-# LANGUAGE QuasiQuotes #-}
--   import Python.Inline
--   import Python.Inline.QQ
--   
--   main :: IO ()
--   main = withPython $ do
--     let input = [1..10] :: [Int]
--     let square :: Int -> Py Int
--         square x = pure (x * x)
--     print =<< runPy $ do
--       fromPy' @[Int] =<< [pye| [ square_hs(x) for x in input_hs ] |]
--   
-- -- Quasiquotation pye captures variables input and -- square from environment and produces python object which -- fromPy' converts to haskell list. As one expect it would -- output: -- --
--   [1,4,9,16,25,36,49,64,81,100]
--   
-- -- Module Python.Inline.QQ provides several quasiquoters with -- different semantics but general rules are: -- --
    --
  1. All python variables ending with _hs are captured from -- environment and converted to python objects according to their -- ToPy instance.
  2. --
  3. Syntax errors in embedded python will be caught during -- compilation.
  4. --
  5. All code interacting with python must be in Py monad which -- could be run using runPy.
  6. --
  7. Python interpreter must be initialized before calling any python -- code.
  8. --
module Python.Inline -- | Initialize python interpreter. If interpreter is already initialized -- it's a noop. Calling after python was shut down will result in error. initializePython :: IO () -- | Destroy python interpreter. finalizePython :: IO () -- | Bracket which ensures that action is executed with properly -- initialized interpreter withPython :: IO a -> IO a -- | Monad for code which is interacts with python interpreter. Only one -- haskell thread can interact with python interpreter at a time. -- Function that execute Py make sure that this invariant is -- held. Also note that all code in Py monad is executed with -- asynchronous exception masked, but liftIO removes mask. data Py a -- | Execute python action. It will take and hold global lock while code is -- executed. Python exceptions raised during execution are converted to -- haskell exception PyError. runPy :: Py a -> IO a -- | Same as runPy but will make sure that code is run in python's -- main thread. It's thread in which python's interpreter was -- initialized. Some python's libraries may need that. It has higher call -- overhead compared to runPy. runPyInMain :: Py a -> IO a -- | Some python object. Since almost everything in python is mutable it -- could only be accessed only in IO monad. data PyObject -- | Python exception converted to haskell. data PyError -- | Python exception. Contains exception type and message as strings. PyError :: !PyException -> PyError -- | It's not possible to convert given python value to a haskell value BadPyType :: PyError -- | Data type is suitable but value is outside of allowed range. For -- example attempting to convert 1000 to Word8 will result in -- this exception. OutOfRange :: PyError -- | Initialization of python interpreter failed PyInitializationFailed :: PyError -- | Python interpreter is not initialized PythonNotInitialized :: PyError -- | Python interpreter is not initialized PythonIsFinalized :: PyError -- | Python exception converted to haskell value data PyException PyException :: !String -> !String -> !PyObject -> PyException -- | Exception type as a string [$sel:ty:PyException] :: PyException -> !String -- | String representation of an exception [$sel:str:PyException] :: PyException -> !String -- | Exception object [$sel:exception:PyException] :: PyException -> !PyObject -- | Convert haskell value to a python object. toPy :: ToPy a => a -> Py PyObject -- | Convert python object to haskell value. All python exceptions which -- happen during execution will be converted to PyError. fromPyEither :: FromPy a => PyObject -> Py (Either PyError a) -- | Convert python object to haskell value. Will return Nothing -- if BadPyType or OutOfRange is thrown. Other python -- exceptions are rethrown. fromPy :: FromPy a => PyObject -> Py (Maybe a) -- | Convert python object to haskell value. Throws exception on failure. fromPy' :: FromPy a => PyObject -> Py a -- | Convert haskell value to python value. class ToPy a -- | Convert python object to haskell value. class FromPy a