{"id":13508688,"url":"https://github.com/urbanserj/hsnif","last_synced_at":"2025-10-26T14:57:24.373Z","repository":{"id":6480035,"uuid":"7720187","full_name":"urbanserj/hsnif","owner":"urbanserj","description":"Tool that allows to write Erlang NIF libraries in Haskell","archived":false,"fork":false,"pushed_at":"2013-06-14T18:26:12.000Z","size":128,"stargazers_count":25,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T11:33:38.579Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/urbanserj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-01-20T18:44:27.000Z","updated_at":"2025-02-01T14:35:48.000Z","dependencies_parsed_at":"2022-07-19T03:32:04.971Z","dependency_job_id":null,"html_url":"https://github.com/urbanserj/hsnif","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/urbanserj/hsnif","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/urbanserj%2Fhsnif","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/urbanserj%2Fhsnif/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/urbanserj%2Fhsnif/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/urbanserj%2Fhsnif/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/urbanserj","download_url":"https://codeload.github.com/urbanserj/hsnif/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/urbanserj%2Fhsnif/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281121687,"owners_count":26447217,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-26T02:00:06.575Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T02:00:56.988Z","updated_at":"2025-10-26T14:57:24.338Z","avatar_url":"https://github.com/urbanserj.png","language":"Haskell","funding_links":[],"categories":["Native Implemented Functions","Languages Integration"],"sub_categories":[],"readme":"Hsnif allows to write Erlang NIF libraries in Haskell.\n\nIntro\n-----\n\nHsnif consists of two parts:\n\n* Rebar plugin that compilates Haskell code to shared library\n* Haskell library which is an interface to functions and types of Erlang NIF library\n\nRebar plugin\n------------\n\nRebar plugin implements `compile` and `clean` commands.\n\nTo add rebar plugin to a new project, add following lines to rebar.config:\n\n```erlang\n{deps, [\n  {hsnif, \".*\", {git, \"https://github.com/urbanserj/hsnif.git\", \"master\"}}\n]}.\n{plugin_dir, \"deps/hsnif/src\"}.\n{plugins, [hsnif]}.\n```\n\n\nFor specifying Target, Source and Compilation options (the last is optional) these lines need to be added:\n\n```erlang\n{hsnif_spec, [\n  {\"priv/target.so\", \"hs_src/Source.hs\", [\n    {cflags, [\"-O\"]},\n    {ldflags, []}\n  ]}\n]}.\n```\n\n\nHaskell code\n------------\n\nAll exported from Source file functions will be NIF functions, and each of them should satisfy the following criteria:\n\n* Each function's argument and return value should be an instance of the class `ErlTerm` (see below)\n* First argument is optional, it should be `ErlNifEnv`\n\nExample:\n\n```haskell\nid :: ErlNifTerm -\u003e ErlNifTerm\nsum :: Int -\u003e Int -\u003e Int\nreverse :: ErlNifEnv -\u003e ErlNifTerm -\u003e IO ErlNifTerm\ntratata :: ErlNifEnv -\u003e IO ErlNifTerm\n```\n\n\nForeign.Erlang.Nif\n------------------\n\nThis haskell library is a part of hsnif and it is an interface to functions and types of Erlang NIF library.\n\nTo convert between Erlang and Haskell types class `ErlTerm` is used. Instance of the class `ErlTerm` must implement two functions:\n`toErlNifTerm` (haskell to erlang term convertation) and `fromErlNifTerm` (vice versa).\n\n```haskell\nclass ErlTerm a where\n  toErlNifTerm :: ErlNifEnv -\u003e a -\u003e IO ErlNifTerm\n  fromErlNifTerm :: ErlNifEnv -\u003e ErlNifTerm -\u003e IO a\n```\n\nFollowing instances already exist in the `Foreign.Erlang.Nif` library:\n\n```haskell\nErlTerm Char\nErlTerm Double\nErlTerm Int32\nErlTerm Int64\nErlTerm Word32\nErlTerm Word64\nErlTerm ()\nIntegral a =\u003e ErlTerm a\nErlTerm CStringLen\nErlTerm CString\nErlTerm ErlAtom\nErlTerm ErlNifBinary\nErlTerm ErlNifTerm\nErlTerm a =\u003e ErlTerm [a]\nErlTerm a =\u003e ErlTerm (IO a)\nErlTerm a =\u003e ErlTerm (ErlTuple a)\nErlTerm (ErlBinary String)\nErlTerm (ErlBinary CStringLen)\n(ErlTerm a, ErlTerm b) =\u003e ErlTerm (a, b)\n(ErlTerm a, ErlTerm b, ErlTerm c) =\u003e ErlTerm (a, b, c)\n(ErlTerm a, ErlTerm b, ErlTerm c, ErlTerm d) =\u003e ErlTerm (a, b, c, d)\n```\n\nTo create a new instance of the class `ErlTerm` for arbitrary type add an instance for this type to source file.\n\nExample:\n\n```haskell\nimport Data.ByteString\nimport Foreign.C.String\n\ninstance ErlTerm (ByteString) where\n  toErlNifTerm env x =\n    useAsCStringLen x $ \\cstr -\u003e\n    toErlNifTerm env (ErlBinary cstr)\n  fromErlNifTerm env x = do\n    ErlBinary cstr \u003c- fromErlNifTerm env x :: IO (ErlBinary CStringLen)\n    packCStringLen cstr\n```\n\nonLoad and onUnload\n-------------------\n\nYou 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:\n\n```haskell\nonLoad :: ErlNifEnv -\u003e Ptr (Ptr ()) -\u003e IO ErlNifTerm\nonLoad :: ErlNifEnv -\u003e IO ErlNifTerm\nonLoad :: Ptr (Ptr ()) -\u003e IO ErlNifTerm\nonLoad :: IO ErlNifTerm\n\nonUnload :: ErlNifEnv -\u003e Ptr () -\u003e IO ()\nonUnload :: ErlNifEnv -\u003e IO ()\nonUnload :: Ptr () -\u003e IO ()\nonUnload :: IO ()\n```\n\nLook for semantics of these functions in Erlang NIF documentation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Furbanserj%2Fhsnif","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Furbanserj%2Fhsnif","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Furbanserj%2Fhsnif/lists"}