Haskell in Production: Caribou

In our Haskell in Production series, we interview developers and technical leaders from companies that use Haskell for real-world tasks. We cover benefits, downsides, common pitfalls, and tips for building useful Haskell products.

Our today’s guest is Syed Jafri, a Senior Software Engineer at Caribou – a company that helps car owners get quotes on refinancing and insurance. He managed to successfully pitch and introduce Haskell at Caribou. They are currently using it for some of the services and have 9 Haskellers at their company.

Read about his experience introducing Haskell at Caribou below.

How Caribou uses Haskell in production

Could you give our readers a brief introduction to Caribou and your role there?

Caribou helps people save money on their car. We help users quickly get quotes to refinance their auto loan, reducing their payments. On the other side, we get users auto insurance quotes so they can get the best rate.

I’m Syed Jafri, an early engineer at Caribou that has had the chance to see the company grow. I was helped in answering these questions by Jason Fry, who joined Caribou in September 2021 as part of the Insurance team to create a web experience for users to see great quotes on auto insurance.

Where in your stack do you use Haskell?

We use it for our Insurance platform and integrations services. Specifically, we have created two different eventing systems and one REST API with it.

Why did you decide to choose Haskell for the project?

At the beginning of the pandemic, we were growing rapidly and needed more engineers to help. We had a difficult time with hiring engineers that met our bar. Our stack at the time was mainly Ruby and Typescript and those markets felt really competitive. Interviewing was really taxing, and sometimes it felt difficult to find candidates.

At the same time, I was interested in eventually pursuing a Haskell role but felt that it was extremely competitive as a candidate. Recruiters mentioned they would get back to you in three months because they had a backlog. This was a stark difference from hiring Ruby and Typescript engineers.

I eventually pitched using Haskell for the following reasons:

  • If we hire Haskell Engineers, we would be hiring from a different pool of candidates.
  • Engineers who are driven enough to learn Haskell have characteristics that also make them generally high-quality engineers
  • There’s a lot of interest in Haskell, but very few Haskell roles.

Basically, it’s similar to the Python paradox. Which is interesting, since your interview with Mercury also mentioned similar advantages.

We linked up with Andrew Boardman, who was the Executive Director of the Haskell Foundation at the time. He gave us a few case studies of other organizations who have used Haskell that he worked with, including an organization that was primarily interested in Haskell due to their success with hiring. We ended up working with our CTO, who was interested in seeing how the response was when we posted a job description, and ended up generating far more applicants than we expected, many of which were very high quality. We could have easily staffed 2-3 more teams than we needed to with good candidates.

Are there any specific qualities of Haskell that make it valuable for your use case?

Here are the qualities that made it valuable for us:

  • Quick for us to create MVPs.
  • All of its commonly referenced benefits, such as:
    • Ease of refactoring.
    • Confidence in reliability and correctness. Personally, this gives me much less anxiety when I sleep at night.
    • Strong type system. Compared to Typescript, sum types are much more natural.

Could you describe any of the challenges you ran into while building the project and how you solved it?

Sometimes there isn’t good library support but most of what we have been missing can be pretty easy to build out. For example, we created a custom library for segment and rollbar (that works with katip).

In my opinion, if you are building software that is primarily data transformation, communication with other systems, and other BLOBA (Boring Line of Business Applications) type of work, which is a lot of software, most of what you need is available. And what’s not there, it isn’t that bad to write it yourself. For example, it’s not that hard to generate Haskell types from an OpenAPI spec or existing TypeScript types and call their API.

Could you list some Haskell libraries that your team found very useful while developing Caribou and that you would like to feature?

  • servant: It has a higher learning overhead, but the servant cookbook is pretty good, and it provides us with type safety that we feel is valuable.
  • postgres-simple: I spent a lot of time trying to find a database library to use. postgres-simple is honestly fine starting out, and we don’t have many complicated SQL queries.
  • hw-kafka-client: Works well and is pretty well documented, which I appreciate.
  • katip: Logging library that allows you to add context and works with aeson.
  • fourmolu: More customizable than ormolu.

What kind of an effect system do you use: RIO, mtl, or something more advanced?

We use this:

import qualified Control.Monad.Reader as Reader
import qualified Data.Pool as Pool
import qualified Database.PostgreSQL.Simple as Simple
import qualified UnliftIO

newtype App extras a = 
  App {unApp :: Reader.ReaderT (Environment extras) IO a}
    deriving
	( Applicative
, Functor
, Monad
    , MonadFail
    , IO.MonadIO
	, Reader.MonadReader (Environment extras)
	, UnliftIO.MonadUnliftIO
	)

data Environment extras = Environment
  { messageDbConfigPool :: Pool.Pool Simple.Connection
  —- etc
  }

Could you tell us a little bit about your experience using Elm on frontend together with Haskell?

Many of us had previous Elm experience, but the ones who didn’t were able to pick it up very quickly. We love Elm for its simplicity, it’s opinionated and good architecture, and top notch compiler messages. We recommend it as your first consideration for a frontend language.

We used servant-elm to generate Elm code from our Haskell API. That didn’t work as well as we had hoped because support for mixed sum types wasn’t as good as we would have liked, and we made some decisions that we later regretted because we weren’t diligent enough. Those decisions were heavily influenced by the generated code and we would never have chosen them otherwise. So if you want to use servant-elm or a similar tool, try it out with your most complicated types first, and continue to write good code that is organized well.

What tips would you give to developers that want to introduce Haskell in their workplace?

I occasionally see posts in /r/haskell and other Haskell communities about developers who seem enthusiastic about introducing Haskell to their workplace but are worried about how it might go. I also found it very nerve wracking thinking about what if people don’t like it, if I might fail, things might not go well.

At the same time, I feel like the feedback is usually discouraging, and there’s too much FUD thrown out there. I personally feel it’s worth at least an experiment. If you are still hesitant or nervous, reach out to other organizations or even the Haskell Foundation. The Haskell Foundation offered an immense amount of support and just informing leaders in our organization of their support was valuable to persuade any decision makers.

In the end, we have had a year of success, have 9 Haskellers, and a lot of enthusiasm about Haskell in the org.


Hope you enjoyed our interview with Syed!

For more interviews with companies that use Haskell to solve real-world problems, check out our Haskell in Production series. Also, be sure to follow us on Twitter or subscribe to our mailing list (via form below) to receive new Serokell articles via email.

Haskell courses by Serokell
More from Serokell
Write Rust like a Haskeller ThumbnailWrite Rust like a Haskeller Thumbnail
haskell dependency analysis imagehaskell dependency analysis image
Haskell in Production: Channable thumbnailHaskell in Production: Channable thumbnail