Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/urbanserj/hsnif
Tool that allows to write Erlang NIF libraries in Haskell
https://github.com/urbanserj/hsnif
Last synced: about 1 month ago
JSON representation
Tool that allows to write Erlang NIF libraries in Haskell
- Host: GitHub
- URL: https://github.com/urbanserj/hsnif
- Owner: urbanserj
- License: mit
- Created: 2013-01-20T18:44:27.000Z (almost 12 years ago)
- Default Branch: master
- Last Pushed: 2013-06-14T18:26:12.000Z (over 11 years ago)
- Last Synced: 2024-08-02T02:12:40.363Z (4 months ago)
- Language: Haskell
- Size: 125 KB
- Stars: 26
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- freaking_awesome_elixir - Haskell - Tool that allows to write Erlang NIF libraries in Haskell. (Native Implemented Functions)
- fucking-awesome-elixir - hsnif - Tool that allows to write Erlang NIF libraries in Haskell. (Native Implemented Functions)
- beamtoolbox - [erl
- awesome-elixir - hsnif - Tool that allows to write Erlang NIF libraries in Haskell. (Native Implemented Functions)
README
Hsnif allows to write Erlang NIF libraries in Haskell.
Intro
-----Hsnif consists of two parts:
* Rebar plugin that compilates Haskell code to shared library
* Haskell library which is an interface to functions and types of Erlang NIF libraryRebar plugin
------------Rebar plugin implements `compile` and `clean` commands.
To add rebar plugin to a new project, add following lines to rebar.config:
```erlang
{deps, [
{hsnif, ".*", {git, "https://github.com/urbanserj/hsnif.git", "master"}}
]}.
{plugin_dir, "deps/hsnif/src"}.
{plugins, [hsnif]}.
```For specifying Target, Source and Compilation options (the last is optional) these lines need to be added:
```erlang
{hsnif_spec, [
{"priv/target.so", "hs_src/Source.hs", [
{cflags, ["-O"]},
{ldflags, []}
]}
]}.
```Haskell code
------------All exported from Source file functions will be NIF functions, and each of them should satisfy the following criteria:
* Each function's argument and return value should be an instance of the class `ErlTerm` (see below)
* First argument is optional, it should be `ErlNifEnv`Example:
```haskell
id :: ErlNifTerm -> ErlNifTerm
sum :: Int -> Int -> Int
reverse :: ErlNifEnv -> ErlNifTerm -> IO ErlNifTerm
tratata :: ErlNifEnv -> IO ErlNifTerm
```Foreign.Erlang.Nif
------------------This haskell library is a part of hsnif and it is an interface to functions and types of Erlang NIF library.
To convert between Erlang and Haskell types class `ErlTerm` is used. Instance of the class `ErlTerm` must implement two functions:
`toErlNifTerm` (haskell to erlang term convertation) and `fromErlNifTerm` (vice versa).```haskell
class ErlTerm a where
toErlNifTerm :: ErlNifEnv -> a -> IO ErlNifTerm
fromErlNifTerm :: ErlNifEnv -> ErlNifTerm -> IO a
```Following instances already exist in the `Foreign.Erlang.Nif` library:
```haskell
ErlTerm Char
ErlTerm Double
ErlTerm Int32
ErlTerm Int64
ErlTerm Word32
ErlTerm Word64
ErlTerm ()
Integral a => ErlTerm a
ErlTerm CStringLen
ErlTerm CString
ErlTerm ErlAtom
ErlTerm ErlNifBinary
ErlTerm ErlNifTerm
ErlTerm a => ErlTerm [a]
ErlTerm a => ErlTerm (IO a)
ErlTerm a => ErlTerm (ErlTuple a)
ErlTerm (ErlBinary String)
ErlTerm (ErlBinary CStringLen)
(ErlTerm a, ErlTerm b) => ErlTerm (a, b)
(ErlTerm a, ErlTerm b, ErlTerm c) => ErlTerm (a, b, c)
(ErlTerm a, ErlTerm b, ErlTerm c, ErlTerm d) => ErlTerm (a, b, c, d)
```To create a new instance of the class `ErlTerm` for arbitrary type add an instance for this type to source file.
Example:
```haskell
import Data.ByteString
import Foreign.C.Stringinstance ErlTerm (ByteString) where
toErlNifTerm env x =
useAsCStringLen x $ \cstr ->
toErlNifTerm env (ErlBinary cstr)
fromErlNifTerm env x = do
ErlBinary cstr <- fromErlNifTerm env x :: IO (ErlBinary CStringLen)
packCStringLen cstr
```onLoad and onUnload
-------------------You can specify two optional functions `onLoad` and `onUnload` in the source file. These functions will be called on loading and on unloading the module respectively and should be one of the following types:
```haskell
onLoad :: ErlNifEnv -> Ptr (Ptr ()) -> IO ErlNifTerm
onLoad :: ErlNifEnv -> IO ErlNifTerm
onLoad :: Ptr (Ptr ()) -> IO ErlNifTerm
onLoad :: IO ErlNifTermonUnload :: ErlNifEnv -> Ptr () -> IO ()
onUnload :: ErlNifEnv -> IO ()
onUnload :: Ptr () -> IO ()
onUnload :: IO ()
```Look for semantics of these functions in Erlang NIF documentation.