# The Hazy Haskell Compiler

**URL:** https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497
**Category:** Announcements
**Created:** [January 7, 2026, 9:35am UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497 "2026-01-07T09:35:20Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)
#### Post date: [January 7, 2026, 9:35am UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/1 "2026-01-07T09:35:20Z")

</div>

I’m proud to showcase Hazy, my Haskell compiler. This is a project I have been working on in private for 3 years. It’s unfortunately not finished but it’s at the point where it’s fairly interesting. The type checker largely works and it’s able to generate Javascript. Though I haven’t tested the generated code yet.

My main goal with this is to explore how I can make Haskell more performant. I plan to implement lifetimes, linear types, levity polymorphism etc, like I did with my toy language [Aith](https://github.com/superstar64/aith).

> **[GitHub - Superstar64/Hazy: The Hazy Haskell Compiler](https://github.com/Superstar64/Hazy)**
>
> The Hazy Haskell Compiler

---

<div class="post-metadata">

### Author: ![enobayram](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/enobayram/32/1815_2.png) [@enobayram](https://discourse.haskell.org/u/enobayram)
#### Post date: [January 7, 2026, 10:45am UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/2 "2026-01-07T10:45:15Z")

</div>

Very interesting! There are some very good ideas here, looking forward to seeing where you take Hazy!

---

<div class="post-metadata">

### Author: ![simonpj](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/simonpj/32/890_2.png) [@simonpj](https://discourse.haskell.org/u/simonpj)
#### Post date: [January 7, 2026, 10:55am UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/3 "2026-01-07T10:55:48Z")

</div>

It’s great to see more diversity in the Haskell-compiler world.

It’s always good to say what the main goal(s) are, so that others can learn from what you are doing. (E.g. for microHs it’s “small footprint, compiles fast”) And you do indeed say what your main goal is:

> [@superstar64](#):
>
> My main goal with this is to explore how I can make Haskell more performan

Do you mean “compiles fast” or “runs fast”? I think probably the latter.

If you mean “runs fast” do you have any ideas for how to make Haskell run fast? GHC tries to do that too, but you may well have new ideas.

---

<div class="post-metadata">

### Author: ![Kleidukos](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/kleidukos/32/1213_2.png) [@Kleidukos](https://discourse.haskell.org/u/Kleidukos)
#### Post date: [January 7, 2026, 10:56am UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/4 "2026-01-07T10:56:06Z")

</div>

Great news, thanks a lot for sharing your work!

---

<div class="post-metadata">

### Author: ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)
#### Post date: [January 7, 2026, 11:06am UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/5 "2026-01-07T11:06:47Z")

</div>

> [@simonpj](#):
>
> Do you mean “compiles fast” or “runs fast”? I think probably the latter.
> 
> If you mean “runs fast” do you have any ideas for how to make Haskell run fast? GHC tries to do that too, but you may well have new ideas.

Yes, I do want to make Haskell run faster, but my approach will be different from GHC’s. My plan is to effectively treat current Haskell as legacy and bolt-on a bunch of extensions that let you write fast code. That way you can have nice and friendly Haskell by default but optimize to C-level if you really need to.

My current plans to achieve this are to first implement current Haskell using Preceus (reference counting). This has the advantage that it doesn’t need a fancy runtime and would make Haskell follow C++'s “you don’t pay for what you don’t use” principle. Once that’s done, then I can focus on adding things like strict functions, multiargument functions, effectful functions, levity polymorphism, pointers (with lifetimes), and whatever else I would need. Then finally, when LLVM sees C-like code, it can optimize like C-like code.

I should note these plans are for the far future. Right now I need to focus on actually getting the compiler to work and I plan to do that with my test Javascript backend.

---

<div class="post-metadata">

### Author: ![Kleidukos](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/kleidukos/32/1213_2.png) [@Kleidukos](https://discourse.haskell.org/u/Kleidukos)
#### Post date: [January 7, 2026, 11:10am UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/6 "2026-01-07T11:10:08Z")

</div>

That’s very ambitious, I’d love to contribute in the future. 🙂

---

<div class="post-metadata">

### Author: ![prophet](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/prophet/32/5031_2.png) [@prophet](https://discourse.haskell.org/u/prophet)
#### Post date: [January 7, 2026, 12:31pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/7 "2026-01-07T12:31:24Z")

</div>

How are you planning on dealing with reference cycles?

These are quite common in Haskell since e.g. `repeat` creates a cyclical list and even very basic patterns like defining `Applicative` via `ap` create a cycle between the `Applicative` and `Monad` dictionaries.

---

<div class="post-metadata">

### Author: ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)
#### Post date: [January 7, 2026, 12:37pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/8 "2026-01-07T12:37:56Z")

</div>

I already answer this a while ago:

> [@Plans to bring FBIP/FP2 in Haskell?](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/11):
>
> Correct. Though it’s okay to have global recursive thunks because they don’t have a reference count. Right now my plan is to use lambda lifting to rewrite all recursive let bindings into global let bindings.

Basically, you remove the sharing for local recursive bindings. It’s the same as if you rewrote all your (local) recursive code with the non sharing fix.

```haskell
fix f = f (fix f)

```

For the `repeat` example, evaluting `n` cells will be `O(n)` memory.

---

<div class="post-metadata">

### Author: ![augustss](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/augustss/32/887_2.png) [@augustss](https://discourse.haskell.org/u/augustss)
#### Post date: [January 7, 2026, 3:10pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/9 "2026-01-07T15:10:10Z")

</div>

Very cool! Welcome to the Haskell implementers crowd.

Haskell is a rather unspecific term. What version of Haskell do you implement?

---

<div class="post-metadata">

### Author: ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)
#### Post date: [January 7, 2026, 3:37pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/10 "2026-01-07T15:37:37Z")

</div>

> Haskell is a rather unspecific term. What version of Haskell do you implement?

I currently plan on implementing Haskell 2010-ish plus DataKinds, GADTs and a few other things. I chose these because I need them for bootstrapping. I don’t really plan on implementing things like multiparameter type classes, type families or anything else GHC specific at the moment. Once I have Haskell 2010 in a functional state, I plan on going in different direction and implementing my own extensions.

I mentioned this in the readme, but I already have some custom extensions. Let me highlight these two:

# Extended Local Declarations

```haskell
sortBy :: forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy by = map runBy . sort . map By where
  import Data.List (sort)
  newtype By = By { runBy :: a }
  instance Eq By where
    a == b
      | EQ <- compare a b = True
      | otherwise = False
  instance Ord By where
    compare (By a) (By b) = by a b

```

# Of Guard Blocks

```haskell
addFail maybe1 maybe2
  of
    Just value1 <- maybe1
    Just value2 <- maybe2
    value1 + value2
  of
    0

```

---

<div class="post-metadata">

### Author: ![augustss](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/augustss/32/887_2.png) [@augustss](https://discourse.haskell.org/u/augustss)
#### Post date: [January 7, 2026, 3:43pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/11 "2026-01-07T15:43:44Z")

</div>

With Extended Local Declaration, are data types generative, i.e., with `data` inside a recursion, does each iteration get a new data type? I’m guessing, no.

---

<div class="post-metadata">

### Author: ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)
#### Post date: [January 7, 2026, 3:47pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/12 "2026-01-07T15:47:34Z")

</div>

> With Extended Local Declaration, are data types generative, i.e., with `data` inside a recursion, does each iteration get a new data type? I’m guessing, no.

I’m not sure how to answer this. As of now, `data` and `class` declarations don’t generate code and `instance` declarations are (effectively) desugared into terms. I guess the answer would be yes. In the same way that polymorphic recursion gives you a new type each iteration, but in a way that the runtime doesn’t care.

---

<div class="post-metadata">

### Author: ![augustss](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/augustss/32/887_2.png) [@augustss](https://discourse.haskell.org/u/augustss)
#### Post date: [January 7, 2026, 4:00pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/13 "2026-01-07T16:00:19Z")

</div>

If this typechecks, it’s not generative.

```haskell
f 0 = []
f n =
  let data T = A
  in A : f (n-1)

```

---

<div class="post-metadata">

### Author: ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)
#### Post date: [January 7, 2026, 4:02pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/14 "2026-01-07T16:02:41Z")

</div>

That does not type check, `T` escapes.

I don’t have integer patterns (or generalization) at the moment, but here’s a modified version and the actual message:

```haskell
module Augestss where

f _ = []
f n =
  let data T = A
  in A : f (n-1)

```

```haskell
Augestss.hs:6:7 error: escaping type: `T`

```

---

<div class="post-metadata">

### Author: ![augustss](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/augustss/32/887_2.png) [@augustss](https://discourse.haskell.org/u/augustss)
#### Post date: [January 7, 2026, 4:42pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/15 "2026-01-07T16:42:12Z")

</div>

OK, escaping was not the problem I was referring to. I’ll see if I can come up with a different example.

---

<div class="post-metadata">

### Author: ![augustss](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/augustss/32/887_2.png) [@augustss](https://discourse.haskell.org/u/augustss)
#### Post date: [January 7, 2026, 4:48pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/16 "2026-01-07T16:48:16Z")

</div>

I noticed that you do not support prefix negation (i.e. `-x`). That’s what I started with for MicroHs, but I gave up on it, because I wanted to use code written by other people. So if you don’t want to write all the code yourself, I recommend against it.

---

<div class="post-metadata">

### Author: ![augustss](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/augustss/32/887_2.png) [@augustss](https://discourse.haskell.org/u/augustss)
#### Post date: [January 7, 2026, 5:52pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/17 "2026-01-07T17:52:16Z")

</div>

I’d like to run a program. How do I do that?

---

<div class="post-metadata">

### Author: ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)
#### Post date: [January 7, 2026, 6:10pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/18 "2026-01-07T18:10:59Z")

</div>

Uhh, unfortunately, I’m not that far along yet 😔. Literally none of base is implemented yet. It’s all `x = error "todo"`. I literally just finished the Javascript generator today and decided it’s a reasonable point to publish it. All you can do is generate Javascript and look at it.

There’s also some low hanging fruit that I need to get around to implementing like lambdas and case expressions.

---

<div class="post-metadata">

### Author: ![TerrorJack](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/terrorjack/32/5155_2.png) [@TerrorJack](https://discourse.haskell.org/u/TerrorJack)
#### Post date: [January 7, 2026, 6:52pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/19 "2026-01-07T18:52:52Z")

</div>

using lambda lifting to deal with mutually recursive bindings is a very neat idea. does it also work with mutable references?

---

<div class="post-metadata">

### Author: ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)
#### Post date: [January 7, 2026, 6:59pm UTC](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497/20 "2026-01-07T18:59:35Z")

</div>

No it does not. `IORef` will leak by default and will have to be manually freed. `STRef`s will be freed when the computation ends. This can be enhanced a bit with monadic regions to allow for scoping.

Again in Aith, I have a region effect system which is equivalent to monadic regions and based on boolean unification. I plan to put it or something like it into Hazy at some point.

[Next page](https://discourse.haskell.org/t/the-hazy-haskell-compiler/13497.md?page=2)
