Is Haskell lacking low-level system libraries?

Is Haskell lacking in bindings for pcap and eBPF, especially considering that the existing pcap bindings are outdated and not maintained, and there are no bindings similar to libbpf for eBPF in Haskell’s ecosystem?

4 Likes

I personally am missing:

4 Likes

honestly an eBPF binding would be great I think.

4 Likes

I agree, but for now, I only found this tool for eBPF bytecode, it’s too low-level. It’s frustrating that I don’t have the ability to encapsulate it myself.

1 Like

It’s not especially hard to write bindings for low level things in Haskell. The FFI is great, cabal treats C basically as a first-class citizen, and verbatim C bindings (pointers and all) are honestly pretty nice to use (and easy to write a “-simple” style layer on top).

So if you have a use for them, I recommend trying it yourself! Even if it’s piecemeal and just what you need.

3 Likes

Do you have a favorite example of a library that uses C bindings and that uses the techniques you mention?

cabal treats C basically as a first-class citizen

no.

Also: anything other than configure and autotools for your cbits is gonna be a major pain in the a**.

2 Likes

I guess the C support isn’t perfect, but I think my point still stands. It’s not that hard to just write C bindings as you need them. Cabal is good enough to handle single-header libraries + simple-ish C libraries in-tree. And Nix (imo the best C package manager by far) is super well integrated with cabal’s C support. If I have a library that uses CMake, I just use Nix and it’s usually trivial (and x-compilation is just some light hacking away to boot.)

sdl2 is probably the best example. It provides .Raw bindings and then “simple” bindings on top. By “simple” I mean a la postgresql-simple. They aren’t super opinionated, but they allow you to use the underlying C library with idiomatic Haskell. So for sdl2, they add:

  • Allocate & marshal pointers
  • Proper ADTs
  • MonadIO
  • Light abstractions (e.g. getKeyboardState :: MonadIO m => m (Scancode -> Bool))
  • StateVar

In terms of “just write bindings when they are missing,” I’ve done this a few times and taken a similar approach to sdl2. Haskell gamedev also doesn’t have everything you’d want, so it’s nice to be able to borrow from C gamedevs (I find they are surprisingly philosophically similar to Haskell ones.)

  • Bindings to cute_c2.h, a single-header 2D collision library. There’s a .C .hsc module and then a Haskell wrapper on top that handles memory management and converting to proper ADTs. The .hsc actually uses phantom types to make the tagged-union C API type-safe.
  • Bindings to sdl-gpu, a high-performance 2D rendering library. This C library is pretty large and is built with CMake. I use Nix to build it. I started with .C bindings, and I used them verbatim for multiple game jams and projects! Once I learned the C library [1], I had a feel for what “simple” bindings would be helpful and now use those.

[1] A key part of using C via FFI is you still need to understand the C library as a C programmer would. For this reason, I don’t consider manual FFI to necessarily be a pure waste of time. There’s thought involved to use Haskell to capture the C author’s intent even at the verbatim FFI level, and going through the FFI process always teaches me the C library along the way.

4 Likes

@ocramz I can also recommend GitHub - haskell-cryptography/libsodium-bindings: Bindings to libsodium for Haskell for nice examples of C bindings.

2 Likes