DEV Community

Paweł Stadnicki
Paweł Stadnicki

Posted on

What F# Knows About Functors and What Comes Next

This post is a short, opinionated reflection on one thing that feels most notably missing in F# today. It provides brief background, references recent discussions on why this gap exists, and ends with a teaser of a possible solution that we will shortly have in our arsenal.

When F# Alone Is Not Enough

Let’s look at something we already have—even if we don’t quite treat it as a first-class citizen. Let's look without precise category-theory definitions, just an intuitive picture.

You may have heard of a Functor

Functor is a great name for a dog.
In programming, you can leave one alone for days
and it will still behave exactly the same, obeying all the laws.

As an F# developer, if you want to play with a Functor, you usually have to name your dog yourself (or your cat — but that would make the metaphor silly).

To be precise: such a pet does exist in F#. But it remains unnamed — unless you use the FSharpPlus library as a kind of dog collar. And while that helps, it’s still not quite the same.

The behavior is present; the abstraction is not.

In F#, the idea of a functor survives without the name — an example of how far the language goes, and where it deliberately stops.

This is not a complaint. It’s a reflection on growth — of the language, and of its ecosystem.

There are things that are simply not expressible in F# today.
The most important of these is the ability to abstract over type constructors themselves.

Full HKT support lets you name, pass around, store, compose, and reason about abstractions—not just use them implicitly through functions.

In F#, we can rely on functorial behavior (map on Option, List, Async, etc.), but we cannot name it, quantify over it, or require it in our own APIs.

Changing a language at its core—for example, by redesigning generics—is an extremely disruptive, breaking change. Scala is a notable example here: because it was designed from the ground up to support HKTs, it was able to implement type classes through its implicits mechanism.
F#, by contrast, is built on .NET’s reified generics, which prioritize runtime performance and cross-language compatibility, but lack the native infrastructure to abstract over containers (F[T]) without complex workarounds.

Don Syme, in his well-known position on type classes, writes:

“I don’t want F# to be the kind of language where the most empowered person in the Discord chat is the person who knows the most category theory or abstract algebra.”

(Please read the full article; this excerpt is intentionally selective and used here only to frame the discussion.)

That position is understandable — and arguably the right one for a mainstream language.

And what about creating a new language altogether?

As Anders Hejlsberg, the creator of C# and TypeScript, recently noted:

Introducing new programming languages in the AI era is inherently disadvantaged: the “best” language for AI is the one it has seen the most.

So, to tackle today's complexities, maybe indeed we should revisit Category Theory?

Yet another CT geek, huh? I'm still learning, but the past few months—after years of trying and abandoning the subject—have brought me to a realization: you either know Category Theory well enough to use it confidently, or you don't use it at all.

A DSL with real HKT support would allows us to define behavior once and lift it across structure. It lets us reason about effects without committing to execution, and about context without sequencing. That’s why functors—and, naturally, comonads—are often the right place to start when designing complex effect systems. They operate at a more fundamental layer than monads: the layer where the meaning of context is defined, before effects are sequenced.

With HKTs, a lot of CT will become more obvious. Almost boring, but surprisingly enjoyable.

And that’s the point.

So Where Does This Leave Us ?

What does not emerge in the open often continues to grow elsewhere.

In 2026, we’ll be able to use more ideas from Category Theory in practice—not by escaping language constraints, but by working with them deliberately. This will happen through a DSL/language being built at BLP: written in F# and extensible with F#.

I have the privilege of being the dumbest person in that room—and of getting to play with these ideas early.

This post is not a reveal of that DSL yet, but simply a short opening note. The concrete parts, with proper credit to authors will be discussed starting in January.

I'm alone in this opinion ?

This year’s Advent of F# calendar reflects a noticeable shift. The majority of contributions focus on domain modeling, types, language tooling (LSPs), and even programming language design, rather than MCP-related topics. At the same time, Tomas Petricek—the long-time advocate of effect systems—continues to deliver excellent lessons on building small, well-structured systems in F#. There is also a promising book coming next year, The Book of Functions, which fits perfectly into this broader reflection.

Top comments (0)