{"id":15010980,"url":"https://github.com/minoki/unboxing-vector","last_synced_at":"2025-04-09T18:35:36.307Z","repository":{"id":56881396,"uuid":"167671318","full_name":"minoki/unboxing-vector","owner":"minoki","description":"A newtype-friendly wrapper for Data.Vector.Unboxed","archived":false,"fork":false,"pushed_at":"2022-09-09T00:44:21.000Z","size":96,"stargazers_count":6,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-06T04:14:46.973Z","etag":null,"topics":["haskell"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/minoki.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","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":"2019-01-26T09:24:25.000Z","updated_at":"2023-02-05T07:38:10.000Z","dependencies_parsed_at":"2022-08-20T23:40:13.413Z","dependency_job_id":null,"html_url":"https://github.com/minoki/unboxing-vector","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minoki%2Funboxing-vector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minoki%2Funboxing-vector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minoki%2Funboxing-vector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minoki%2Funboxing-vector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/minoki","download_url":"https://codeload.github.com/minoki/unboxing-vector/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248088495,"owners_count":21045723,"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","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":["haskell"],"created_at":"2024-09-24T19:38:01.866Z","updated_at":"2025-04-09T18:35:36.286Z","avatar_url":"https://github.com/minoki.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# unboxing-vector: A newtype-friendly variant of unboxed vectors\n\nThis package provides newtype-friendly wrappers for `Data.Vector.Unboxed` in [`vector` package](http://hackage.haskell.org/package/vector).\n\n## Description\n\nSuppose you define a newtype for `Int` and want to store them in an unboxed vector.\n\n```haskell\nimport qualified Data.Vector.Unboxed as Unboxed\n\nnewtype Foo = Foo Int\n\nvec :: Unboxed.Vector Foo\nvec = Unboxed.generate 10 (\\i -\u003e Foo i)\n```\n\nWith classic `Data.Vector.Unboxed`, you either write _two dozen of lines_ of code to get it work (the exact code is [here](https://github.com/minoki/unboxing-vector/blob/3a152014b9660ef1e2885d6b9c66423064223f63/test/Foo.hs#L36-L63)), or resort to Template Haskell ([`vector-th-unbox` package](http://hackage.haskell.org/package/vector-th-unbox)) to generate it.\n\nNow you have the third option, namely `Data.Vector.Unboxing`.\nWith `Data.Vector.Unboxing`, the amount of code you write is just _two lines_:\n\n```haskell\nimport qualified Data.Vector.Unboxing as Unboxing\n\ninstance Unboxing.Unboxable Foo where\n  type Rep Foo = Int\n\nvec :: Unboxing.Vector Foo\nvec = Unboxing.generate 10 (\\i -\u003e Foo i)\n```\n\n...and if you want to be even more concise, you can derive `Unboxable` instance with `GeneralizedNewtypeDeriving`.\n\nNote that the vector type provided by this package (`Data.Vector.Unboxing.Vector`) is *different* from `Data.Vector.Unboxed.Vector`.\nIf you need to convert `Unboxing.Vector` to `Unboxed.Vector`, or vice versa, use `Unboxing.toUnboxedVector` or `Unboxing.fromUnboxedVector`.\n\nThe module defining the type `Foo` does not need to export its constructor to enable use of `Unboxing.Vector Foo`.\nIn that case, the users of the abstract data type cannot convert between `Unboxing.Vector Int` and `Unboxing.Vector Foo` --- the abstraction is kept!\n\n## For non-newtypes\n\nSuppose you define a data type isomorphic to a tuple, like:\n\n```haskell\ndata ComplexDouble = MkComplexDouble {-# UNPACK #-} !Double {-# UNPACK #-} !Double\n```\n\nIn this example, `ComplexDouble` is isomorphic to `(Double, Double)`, but has a different representation. Thus, you cannot derive `Unboxing.Unboxable` from `(Double, Double)`.\n\nFor such cases, unboxing-vector provides a feature to derive `Unboxable` using `Generic`.\nUse `Unboxing.Generics` newtype wrapper to derive it.\n\n```haskell\n{-# LANGUAGE DeriveGeneric, DerivingVia, UndecidableInstances #-}\n\ndata ComplexDouble = MkComplexDouble {-# UNPACK #-} !Double {-# UNPACK #-} !Double\n  deriving Generic\n  deriving Data.Vector.Unboxing.Unboxable via Data.Vector.Unboxing.Generics ComplexDouble\n```\n\nUnboxing via `fromEnum`/`toEnum` is also available.\nUse `Unboxing.Enum` or `Unboxing.EnumRep` to derive it.\n\n```haskell\n{-# LANGUAGE DerivingVia, UndecidableInstances #-}\n\ndata Direction = North | South | East | West\n  deriving Enum\n  deriving Unboxing.Unboxable via Unboxing.EnumRep Int8 Direction\n```\n\n## Conversion\n\n### Conversion from/to Unboxed vector\n\nYou can use `fromUnboxedVector` and `toUnboxedVector` to convert one vector type to another.\n\n```haskell\nimport qualified Data.Vector.Unboxed as Unboxed\nimport qualified Data.Vector.Unboxing as Unboxing\n\nconvert :: Unboxed.Vector Int -\u003e Unboxing.Vector Int\nconvert vec = Unboxing.fromUnboxedVector vec\n```\n\n### Coercion between Unboxing vectors\n\nYou can use `coerceVector` to convert vector types of different element types, if they have the same representation and have appropriate data constructors in scope.\n\n```haskell\nimport qualified Data.Vector.Unboxing as Unboxing\nimport Data.MonoTraversable (ofold)\nimport Data.Monoid (Sum(..), All, getAll)\n\nsum :: Unboxing.Vector Int -\u003e Int\nsum vec = getSum $ ofold (Unboxing.coerceVector vec :: Unboxing.Vector (Sum Int)) -- OK\n\nand :: Unboxing.Vector Bool -\u003e Bool\nand vec = getAll $ ofold (Unboxing.coerceVector vec :: Unboxing.Vector All) -- fails because the data constructor is not in scope\n```\n\n## Supported GHC versions\n\nThe library itself is tested with GHC 8.0.2 or later.\n\nTo use `GeneralizedNewtypeDeriving` on `Unboxable` class, you need GHC 8.2 or later,\nbecause GND for associated type families became available on that version.\n\n`DerivingVia` is avaliable since GHC 8.6.1.\nThis means that, defining an `Unboxable` instance for user-defined `data` types (like `ComplexDouble` or `Direction` in this document) requires a latest GHC.\n\nIf you want a way to make your `data` types on older GHCs, please [open an issue on GitHub](https://github.com/minoki/unboxing-vector/issues).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminoki%2Funboxing-vector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fminoki%2Funboxing-vector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminoki%2Funboxing-vector/lists"}