haskeller
home :: IO ()

a community portal

Haskell is beautiful, and so are you for wanting to learn it.

Pure functional programming, rendered as a bedazzled brooch pinned to a velvet lapel. Welcome to the jewel box.

Welcome.hs
-- a greeting in two lines
welcome :: String -> IO ()
welcome name = putStrLn ("hello, " <> name <> "!")

main = welcome "friend" >>= \_ -> pure ()
scroll to compose
01

Learn by unfurling.

A patient senior developer who also collects vintage brooches.

Haskell is not a cliff. It is a fern — each frond an approachable curl that leads, recursively, to the next. Begin with pure and fmap. The rest blooms inline.

  • λ
    First 30 minutes. Read the Prelude out loud. Pronounce >>= as bind. Nothing breaks if you say it wrong.
  • First weekend. Build a tiny CLI that reads a file, counts the words, and prints with putStrLn. Celebrate with a cookie.
  • First month. Trip over monads. Recover. Realize the trip was a feature.
Fern.hs
-- a fern is a recursive data structure
data Fern = Frond Fern | Tip

unfurl :: Int -> Fern
unfurl 0 = Tip
unfurl n = Frond (unfurl (n - 1))
02

Compose like cut crystal.

Every function is a facet. Stack facets, and light refracts into programs.

Composition is the native Haskell verb. Where imperative languages say and then, and then, Haskell simply puts a dot between two verbs and lets the pipeline glitter.

Compose.hs
-- f . g . h : read right to left, a flowing sentence
shout :: String -> String
shout = map toUpper

exclaim :: String -> String
exclaim s = s <> "!"

trim :: String -> String
trim = dropWhile isSpace

loud :: String -> String
loud = exclaim . shout . trim
trim String -> String
.
shout String -> String
.
exclaim String -> String
03

Laziness is flowering.

Compute only what blooms into view. The rest waits patiently in the soil.

Laziness isn't a flaw of character — it's a feature of evaluation. A Haskell value is a wrapped seed (a thunk) that only germinates when someone asks to see the flower.

Infinite.hs
-- ones is an infinite list, but we only pick ten
ones :: [Int]
ones = 1 : ones

tenOnes = take 10 ones

-- primes via trial division, also lazily infinite
primes :: [Int]
primes = sieve [2..]
  where sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
A lazy list is a promise — kept only when you ask.
04

Mappend everyone.

A community is a monoid: empty to start, associative by nature, and anything can be combined with anything else.

We gather on a dozen channels and in a hundred timezones. Senior GHC contributors sit next to first-week learners. The category is everyone. Operator is <>. Identity is mempty. You belong here.

Weekly chat nights

A cozy voice-and-text hang every Wednesday. Talk about records, type families, or your sourdough starter.

chat :: IO ()

Mentor atelier

Pair with a patient haskeller for an hour. No question is too small. No digression is too long.

mentor :: Teach -> IO Joy

Jewel box library

Curated reading list — from Learn You a Haskell to Category Theory for Programmers, annotated by humans.

read :: Book -> IO Shine

First-PR nursery

Open-source contributions for beginners, chaperoned. Push your first commit to a real Haskell project this week.

contribute :: Repo -> PR
Community.hs
instance Semigroup Haskeller where
  a <> b = Haskeller { kindness = kindness a + kindness b }

instance Monoid Haskeller where
  mempty = Haskeller { kindness = 0 }

you :: Haskeller
you = mconcat [curiosity, patience, willingnessToAsk]