describe alternatives and similar packages
Based on the "Data" category.
Alternatively, view describe alternatives based on common mentions on social networks and blogs.
-
semantic-source
Parsing, analyzing, and comparing source code across many languages -
lens
Lenses, Folds, and Traversals - Join us on web.libera.chat #haskell-lens -
code-builder
Packages for defining APIs, running them, generating client code and documentation. -
text
Haskell library for space- and time-efficient operations over Unicode text. -
cassava
A CSV parsing and encoding library optimized for ease of use and high performance -
unordered-containers
Efficient hashing-based container types -
compendium-client
Mu (μ) is a purely functional framework for building micro services. -
holmes
A reference library for constraint-solving with propagators and CDCL. -
resource-pool
A high-performance striped resource pooling implementation for Haskell -
primitive
This package provides various primitive memory-related operations. -
binary
Efficient, pure binary serialisation using ByteStrings in Haskell. -
discrimination
Fast linear time sorting and discrimination for a large class of data types -
IORefCAS
A collection of different packages for CAS based data structures. -
dependent-sum
Dependent sums and supporting typeclasses for comparing and displaying them -
reflection
Reifies arbitrary Haskell terms into types that can be reflected back into terms -
dependent-map
Dependently-typed finite maps (partial dependent products) -
orgmode-parse
Attoparsec parser combinators for parsing org-mode structured text! -
scientific
Arbitrary-precision floating-point numbers represented using scientific notation -
streaming
An optimized general monad transformer for streaming applications, with a simple prelude of functions -
text-icu
This package provides the Haskell Data.Text.ICU library, for performing complex manipulation of Unicode text.
WorkOS - The modern identity platform for B2B SaaS
Do you think we are missing an alternative of describe or a related project?
README
describe
describe
is a library that provides the Descriptor s a
applicative functor for describing binary data structures. The underlying binary serialization/deserialization library is cereal
. Instead of describing how this can be useful, I find that the following example best demonstrates what this library can bring to the table.
The Problem
The problem with de/serialization libraries is that you end up having to write both the Get and Put functions yourself, even though they are almost always isomorphic.
{-# LANGUAGE RecordWildCards #-}
import Data.Serialize.Get
import Data.Serialize.Put
data Example = Example { f1 :: Word32
f2 :: Word64
f3 :: Word16
f4 :: Int8 }
putExample ex@Example{..} = do
putWord32le f1
putWord64le f2
putWord16le f3
putWord8 0 -- Put a dummy/unk value
putInt8 f4
getExample = Test <$> getWord32le
<*> getWord64le
<*> getWord16le
<* getWord8 -- Read the dummy/unk value
<*> getInt8
main = do
let ex = Example 31 54 78 92
let bs = runPut (putExample ex)
Right original <- runGet getExample bs
If you're someone like me who develops server emulators and the like, where a game has about ~430 opcodes, defining message structures like this can quickly lead to a burnout. While other libraries exist that can derive de/serialization implementations on a whole data structure via generics, I find that this is too limiting for my needs. Deriving a structure via generics assumes the user is in full control of the structure of the data, but when you're writing a server emulator for some Korean MMO client, many of the packet fields will be unknown, and you'll want to fill it in with some sort of arbitrary value(s) known to work and hide that from the public interface of your message GADT or whatever.
This library allows you to do something like the following:
{-# LANGUAGE GADTs, DataKinds #-}
import Data.Serialize.Descriptor
import Data.Serialize.Descriptor.LE
data Direction = Clientbound | Serverbound | Bidirectional
data PlayerTradeMessage (a :: Direction) where
InitiatePlayerTrade :: { f1 :: Word32,
f2 :: Word16,
f3 :: Word8,
f4 :: Int8 } -> PlayerTradeMessage 'Serverbound
descriptor = InitiatePlayerTrade <$> w32 f1
<*> w16 f2
<*> w8 f3
<* w8 (const 0) -- Ignore this field when deserializing, and put a '0' during serialization.
<*> i8 f4
main = do
let message = InitiatePlayerTrade 31 46 79 81
let bs = serialize message descriptor
Right originalMessage <- deserialize bs descriptor
As an added bonus, the combinator names are minimalistic (2-3 characters long), which helps churn out message structures faster.
I understand that this library is somewhat niche, but hopefully others can find it useful.