What did you accomplish with PureScript in 2019?

Because reflecting on the past year can inspire others, what did you accomplish with PureScript in 2019?


I managed to build a pretty big website which includes a lot of features. It’s the biggest Purescript/Halogen project I’ve ever done and I learned so much by doing it. It made me realise that doing such a big website with Purescript is not only possible, it’s much better than using any other js/whatever lang framework I’ve ever used. So I’m very happy with that. The site is up here: https://listasafnasi.is
but fyi we did a light launch of the website since a lot of data/information is still being fed into the backend system. So we launched it but nobody knows about it. Once the store is up (which is written in Purescript as well) and the english material is in there we will finally announce it. So it might look confusing since it’s solely in Icelandic at the moment.

Now I’m starting every project in Purescript. So i feel I gained a lot from the year 2019 in terms of Purescript development :smile:


Nice job! What went well in your development? And what were some pain points (e.g. needed to build your own library to do X)?

I’m currently building my first real website right now, so I don’t have much to say for 2019, but hopefully 2020 will be different.

1 Like

I don’t usually do Frontend development, so with some haskell background I decided to give Purescript a try.
My stack is Purescript(Halogen 4, Formless, spago)/Haskell (stack, Servant, Persistent) on NixOS.
It’s just an awesome experience overall as a combination of these awesome techs and a lot of learning too.
I think the learning curve with no background in FP should be very steep for other people. Type signatures in Halogen 4 can be very intimidating, but once you overcome that, your productivity just keep soaring. Type holes are your friend.
I hope the Purescript community will keep growing, and everyone benefits from such a nice language/platform.
Looking forward for more Purescript in 2020.


In general development went quite well and especially with things I didn’t expect to be that easy like handling events. On this site there is all kinds of scrolling effects, infinite scroll etc and doing that with the EventSource was a breeze. But when I started out I had only been doing Purescript for so long. I decided to update to Purescript 0.13.3 since the Parser just seemed to give a lot better indication on errors. So I had to build a lot of custom functionality. Halogen made this a lot easier. For example I needed a media browser. Eventually I want to release it but I need to make some adjustments/updates first

I also made the entire admin backend from scratch so that was quite a work. But gradually I got faster using Halogen. I also realised later on in the process that forking older Purescript/Halogen libraries wasn’t such a big deal. For example i have to use the quill editor and forking jmackie (thank you) version of it took only indentation of one line. I added a method for extracting HTML if this is useful to anyone.

I guess the hardest thing was planning. As a beginner I had no idea if the stuff I was making would take a week or a month and sometimes it took a month. I wouldn’t really consider this a problem today. It’s about 6 months since I started and I’m a lot quicker and I can plan things in Purescript better.


I’m a math teacher and I wanted to try something new for the homeworks I give this year. PureScript helps me create random questions so I can give every student a unique homework. Here is an example about conditional probabilities. Just fill in the input with a random positive integer as a seed to generate the questions. The code uses the KaTeX library to display math and lines are drawn with SVG. (Fill in the input with the opposite of the seed to get the answers, but don’t tell my students!)


That’s really cool!

I’ve been wondering whether a such technique (given a seed, exercises are randomly created) would work for coding exercises. For example, if one was trying to learn how to use Foldable for the first time, perhaps one could generate a number of PureScript exercises that follow some “exercise pattern.”

1 Like

It also sounds like you grew a lot as a PureScript developer this past year :slightly_smiling_face:

1 Like

absolutely, and for this I’m really thankful :pray:. The uncertainty is gone and now I can focus on building more apps with it in 2020 which is very exciting :ok_hand:

It would be one of the nicest way to learn PureScript!

The main thing that i accomplished was doing a fairly massive re-factor, essentially a complete re-write of our app but done entirely incrementally and using the compiler and purescript-ide to keep it all together when the problem space was enormously more than i could have kept in my head.

In the process moved the app off of Pux and onto bare Signal library, started using Spago and Parcel as well as structuring the source much much better and significantly improving the code to either (a) reflect all that i’d learnt since writing it the first time or (b) remove the horrible amateur Purescript i wrote while i was learning on the go before.

Nice job! What sort of improvements did you make to the code?

Well, a good example would be a really fundamental data structure (a kind of alternating vertical and horizontal tree) being written in such a way that made it necessary to pattern match on things that were not germane to tree manipulation. I don’t know whether this should have been obvious to me at the time, but it wasn’t. Fundamentally, i moved from modelling this alternating structure in ADT to encoding it within the type parameter internals.

data ParentType = Root LayoutType | Layer LayoutType | Parent LayoutType
data LayerTree a = HasChildren ParentType (Array (LayerTree a)) a
                 | NoChildren a -- applies to unexpanded parents as well
type LSM = LayerTree LayoutData


data Tree a = N a (List (Tree a))

Additionally, when i re-wrote it i was able to make a Data.Tree module that, while specific to our needs, was completely polymorphic and non-domain specific, with useful typeclass instances (functor, foldable and traversable). You can probably imagine what a huge clean up that was when the change ramifies out to a few thousand lines of algorithms.

The other thing i did was to move a lot of code around to reflect the abstractions that we actually had - it’s important to note that my initial cut of this PureScript code was a piecemeal translation of an earlier JavaScript app and so was hardly well architected to begin with.

And i made a complete disjunction between the data format in PureScript algorithms and the data that was thrown over the FFI to D3.js - if i’d read Justin’s “best practices for FFI” before i did that i might well have gone with JSON to D3, but given there are complex callbacks, maybe that wouldn’t have been worth it for us.

Being sure that there was a defined translation to FFI data ensures that refactoring doesn’t cause silent breaks on the JS side.

I made a small web app to show the day’s schedule and time for the lobby of language school I was attending using Halogen 5rc and FFI for PapaParse (CSV) and native Intl. It was nice refamiliarizing with Halogen and getting a little dough on the side.


Yeah, I can see how that would make a huge improvement in your code, especially once it has type class instances.

Sounds like you grew as well this past year!

Great year, the most important for me was developing purescript-selda. Learnt a whole lot along the way about DSLs, generic programming with row types, gadt, etc.

It was great to see that using selda actually benefits compared with writing SQL by hand. Not only because of the type safety but also it composes really vell - it lets you reuse code between queries, so you end up with a powerful and expressive tool that actually produces desired SQL you would normally write by hand - but shorter, safer and with records as results :heart:

Also working towards support for the second backend (sqlite3) and how to design internal components to work with postresql and sqlite3 without sacrificing the power of backend-specific functionality that you can easily add yourself when you need it.
Great to see it working in practice with real-life databases :wink:


Thanks for working on that library!