Trying out Haskell in 2026??
i've heard that pandoc is written in hs. and it makes me want to learn what haskell can do on my programming thinking thingey. Do i need a strong mathematical background?
also pretend that LLMs does not exist.
i've heard that pandoc is written in hs. and it makes me want to learn what haskell can do on my programming thinking thingey. Do i need a strong mathematical background?
also pretend that LLMs does not exist.
It seems that gitlab.haskell.org is down - has it been down long? Is it expected back up? Is it obsolete?
Hello all!
Looking to get into Haskell for self-improvement since I do not have a lot of experience in functional programming (and to keep my skills sharp outside of AI usage).
I am not very imaginative when it comes to coming up with new hobby projects. I would prefer something guided but I also want to become proficient at it (I also cannot pay attention to a video to save my life).
Hi everyone, I've been working on Haskell bindings for libgpiod. I've already uploaded it to Hackage, but it's currently in alpha.
Recently, I received some amazing feedback regarding memory management using bracket, ResourceT, etc. Now, I'm hoping to get some feedback and recommendations on a few other design doubts I have. Thanks in advance!
FilePath vs ByteStringIn Haskell, FilePath is just an alias for String. I've been using it for functions like:
withChip :: FilePath -> (Chip -> IO a) -> IO a
However, libgpiod is often used on embedded devices with limited RAM. I'm wondering if I should use ByteString to minimize memory consumption. Or, since these strings are typically very short (e.g., "/dev/gpiochip0", "gpiochip0"), should I just stick with standard Strings?
In the low-level layer, I used longer, more descriptive names like LineOffset and eventBufferCapacity. But for the high-level implementation, I was hoping to rely on qualified imports to keep names shorter:
LineOffset -> Line.Offset (import qualified Fuyu.GPIO.Line as Line)eventBufferCapacity -> Event.bufferCapacity (import qualified Fuyu.GPIO.EdgeEvent as Event)Is it considered good practice in Haskell to design an API expecting users to rely heavily on qualified imports for namespace management?
In libgpiod, I can wait for specific edge events in a buffer using gpiod_line_request_wait_edge_events. This function guarantees that there is at least one edge event available when it returns successfully (represented in my code as EventReady).
After getting an EventReady, I create a security token that wraps a line request guaranteed to have at least 1 event.
-- | Wait for edge events to occur on requested lines until the specified timeout.
-- Throws 'WaitEdgeEventsFailed' on error.
waitEvents :: Request -> Timeout -> IO (WaitResult ReadyRequest)
waitEvents req timeout = do
res <- unwrapOrThrow WaitEdgeEventsFailed (D.lineRequestWaitEdgeEvents req timeout)
pure $ case res of
D.EventReady -> EventReady (ReadyRequest req)
D.Timeout -> TimeoutResult
-- | Get a specific edge event from the buffer by index.
bufferEvent :: Buffer -> Word -> IO Event
bufferEvent buf idx = unwrapOrThrow ReadEdgeEventsFailed (D.eventBufferGetEvent buf idx)
-- | Process raw edge events directly in the buffer using a callback without intermediate allocations,
-- returning a non-empty list of results.
withRawEvents :: ReadyRequest -> Buffer -> (Event -> IO a) -> IO (NonEmpty a)
withRawEvents readyReq buf action = do
count <- readEventsRaw readyReq buf
results <- forM [0 .. count - 1] $ \idx -> do
ev <- bufferEvent buf (fromIntegral idx)
action ev
case NE.nonEmpty results of
Just ne -> pure ne
Nothing -> ioError (userError "readEvents: expected at least one event from ReadyRequest but got none")
My question is about withRawEvents: should I remove the NonEmpty case verification? Since it's theoretically impossible to have zero events when holding a ReadyRequest token, is it better to just assume it's non-empty or should I keep the defensive check?
Ctrl+CFinally, simple scripts or tests are often terminated with Ctrl+C. To ensure a "clean shutdown", I created this helper:
-- | High-level managed application runner.
-- Automatically handles 'Ctrl+C' ('UserInterrupt'), interrupted system calls ('EINTR' / 'WaitEdgeEventsFailed'),
-- and prints formatted 'GpioException' messages cleanly without uncaught backtraces.
withGpioApp :: IO a -> IO ()
withGpioApp action = void action `catch` handleAppException
where
handleAppException :: SomeException -> IO ()
handleAppException exc
| isUserInterrupt exc = putStrLn "\nLoop terminated successfully!"
| Just (WaitEdgeEventsFailed (Errno 4)) <- fromException exc = putStrLn "\nLoop terminated successfully!"
| Just (gpioErr :: GpioException) <- fromException exc = putStrLn $ "\n[GPIO Exception]: " ++ show gpioErr
| otherwise = throwIO exc
isUserInterrupt :: SomeException -> Bool
isUserInterrupt e = case fromException e of
Just UserInterrupt -> True
_ -> False
I'm not sure if there's a better or more idiomatic way to handle Ctrl+C when using custom exception types like these:
data GpioException
= ChipOpenFailed FilePath Errno
| ChipInfoFailed Errno
| LineInfoFailed Errno
| LineSettingsNewFailed Errno
-- ...
Any feedback or recommendations would be greatly appreciated. I'd love to ensure this library follows Haskell best practices. Thanks!
Calling all Londoners (and people who can get to London)! On Thursday 17th of September, we will be running a pair of talks at the Permutive offices. If you're interested, sign up to the event!
by Teo Camarasu
Rel8 is a Haskell library for writing PostgreSQL statements, built on top of opaleye. It mirrors Haskell syntax and idioms as much as possible to allow writing SQL in a way that is familiar and concise without sacrificing good error messages. This talk will give a practical introduction to rel8: building up from simple examples to some of its more advanced features like aggregations.
by David Binder
In this talk I am going to take a look at how we got to the current Haskell report, how it changed over the decades, and present the work we are currently undertaking to update it. I will present my own ideas on what the role of the language report can be going forward, but we will hopefully also discuss how the language report can fit with the GHC and CLC proposal processes to document and specify the language we love to use.
When: Thursday 17th of September, aiming to start at 19:00
Where: Permutive Offices (EC1M 7AN, 8-10 Charterhouse Buildings, 2nd floor)
What else:
This is an attempt at bringing a regular Haskell event to London, so please be patient with us! We're hoping to run more events in future, so your feedback is greatly appreciated. Look out for our October event!
Hi all,
I've been thinking about building a small tool called"H-vim", not a new editor, just a launcher/bootstrapper that gets you from a clean machine to a fully working, LSP-powered, exact-Vim-keybindings Haskell setup in one command. I used to use code blocks in my college which was simply download and install.. and i liked the fact that it works without a lot of work..
The idea:
H-vim checks for ghcup, GHC, cabal/stack, and HLS. If anything's missing, it offers to install it for you (via ghcup).nvim-lspconfig wired to HLS, sensible tree-sitter-haskell setup, a few Haskell-specific text objects/motions — using NVIM_APPNAME so it never touches or conflicts with your existing Neovim config.Hello, after a few days and having received some amazing advice here, I’m delighted to present my two libraries of bindings for libgpiod.
fuyu-gpio-direct 0.1.0.0: A lib of ‘direct’, almost 1:1, low-level and mid-level bindings to the libgpiod core API. This library was created, taking inspiration from direct-sqlite, with the aim of having two smaller libraries, and serves as a basis for the development of other libraries.
fuyu-gpio 0.0.9.0: The high-level version, featuring better modularity, safer resource management using deterministic `with*/bracket` constructs, and enhanced type safety (security tokens).
Both are now available on Hackage and GitHub. fuyu-gpio repository currently includes five examples. And the last two show how to use managed and transformers to avoid the Pyramid of Doom.
Furthermore, in the repositories for both packages, there is an Dockerfile containing a version of Debian 13 alongside Haskell, for the purpose of cross-compilation.
I’d be delighted to receive suggestions on how to improve both packages, thanks!
This is a toy programming language I created to understand better how lazy functional languages work, after I discovered Haskell and it blew my mind a little, many many years ago.
It went through many iterations over the years, prototypes, etc., and today I'm happy to call this a version 1.
It first was a Lua prototype, that did basic (and slow) expression tree reduction. Then there was a Lua transpiler and a thin runtime. After several iterations, back and forth on the syntax, abandoning and restarting the project, this final version is in Go and uses a G-machine bytecode interpreter.
In essence it's a dynamically typed "lesser Haskell", so probably not meant for anything real, but I'm quite happy with the syntax and I learned a lot on the way.
The repo has:
Repo: https://github.com/Castux/thunky Web playground: https://castux.github.io/thunky/
AI disclaimer: the latest stages of this project were assisted with LLM (G-machine and web port), but the many iterations and prototypes, the lexer-parser-analyzer, etc. were all first hand written, during the last ten years.
I’m supporting a team of ~20 AI engineers and researchers working primarily in Python (FastAPI, PyTorch). Our infrastructure runs across on-prem servers and AWS.
We have 100+ repositories and face severe template drift, inconsistent CI/CD workflows, and zero centralized visibility into what services are deployed where, whether they are healthy, or if they should be decommissioned.
What I need to build:
A tool to generate new microservices and safely parse, validate, and update configs/CI workflows across dozens of active repositories without causing breaks.
backend service that continuously polls and ingests data from: AWS apis, GitHub apis and some external services.
Given that my end users and downstream developers are Python-focused, is building this platform tooling and state aggregator daemon in Haskell a good idea? Convince me why I shouldn’t go with Go, Rust or Python.
I would love to hear from anyone who has used Haskell for similar infrastructure tooling.
Hasql v2 is out. It can now run natively in Haskell with no external dependencies, or the same way it always has, using "libpq". It's the user's choice now. No performance degradation and minimal changes to the API.
Read the attached post for details.
I'm hitting a lot of 404s on Hackage when installing Haskell packages in CI.
Unexpected response 404 for http://objects-us-east-1.dream.io/hackage-mirror/package/data-array-byte-0.1.0.2.tar.gz
I'm running with the default config file for Cabal.
It this happening to anyone else?
Sorry for double posting; I'm trying to reach the Haskell communities that are most active.
So.. I've just released the first version of Mischief, my open-source ECS Game Engine written fully in Haskell.
I've been working almost exclusively on it for the last few months, and I'm proud of the what it ended up being. It was a great experience as my first big Haskell project.
It's meant to be a balanced combination of data-driven game design and functional programming.
If you want to check it out, here's the hackage page. It comes with its own little book written in Haddock, Learn You an ECS for Great Mischief. I recommend checking out the Startup Guide in particular as it contains many small code snippets and a fully working app.
Edit: AI Disclaimer
Since a few people expressed their worries about this, and I suppose it's understandable given the scale of this project and its documentation: No. Absolutely no LLM / AI-assistance was used in making this.
I am personally very much against the use of these tools and would never use them myself, especially for a passion project such as this. Every single line of code and documentation you see was written by me.
Also commented this on the issue tracker here
An xmonad branch which uses river to run on Wayland. It provides a subset of xmonad's interface, just missing ~20 exported declarations that are either not yet implemented, features absent in Wayland, or too X11-specific.
An xmonad-contrib branch. Port of 304 of 334 contrib modules, missing ~50 exported declarations.
This is vibecoded with care - I used to write a lot of Haskell code. So, while it is largely written by claude over many sessions, it's certainly not pure slop - it runs my config quite well without the config needing any modifications (other than switching off use of X11 specific programs). Not everything is working perfectly, but it's usable.
I certainly have not reviewed all the code for correctness, and I'm sure there are bugs. I know that Prompt in xmonad-contrib doesn't look quite right, for example. If others are enthusiastic about this, I could imagine putting some more work into it. However, currently I don't particularly plan on refining / reviewing / maintaining it.