Sometimes, the best way to learn a language is by using a simple, even slightly “weird” goal as an excuse to explore its core concepts. Here, the goal is to extract the sides (apart from the hypotenuse) from a list of Pythagorean triples—but really, it’s just a reason to learn how pattern matching, recursion, and let blocks work in Haskell.

1. A simple pattern-matching refresher

In Haskell, you can deconstruct tuples directly in function arguments. It’s an elegant and expressive way to “take apart” data structures. Let’s define three simple functions to get each element from a 3-tuple:

myFst :: (Int, Int, Int) -> Int
myFst (x, _, _) = x

mySnd :: (Int, Int, Int) -> Int
mySnd (_, x, _) = x

myThrd :: (Int, Int, Int) -> Int
myThrd (_, _, x) = x

The underscores (_) mean “I don’t care about this value.” Only the variable names you use (like x) are bound.

2. Writing a recursive extractor

Let’s say we have a list of triples representing (a, b, c) values (like Pythagorean triples). We want to extract two lists: one with the first element of each triple, and one with the second.

We can do this recursively:

myExtractor :: [(Int, Int, Int)] -> ([Int], [Int])
myExtractor [] = ([], [])
myExtractor (x:xs) = ((myFst x):xs1, (mySnd x):xs2)
    where (xs1, xs2) = myExtractor xs 

Let’s break this down:

This pattern—matching the head/tail, then combining recursive results—is the backbone of functional recursion in Haskell.

3. Introducing let blocks

The where clause is great for binding helper values, but sometimes you need more control over the scope. That’s where let and in come in. Here’s a version of myExtractor that uses them:

myExtractor2 :: [(Int, Int, Int)] -> ([Int], [Int])
myExtractor2 [] = ([], [])
myExtractor2 (x:xs) =
    let (xs1, xs2) = myExtractor xs 
        a = 3
    in (((myFst x) + a):xs1, (mySnd x):xs2)

This version does the same thing, but introduces a new local variable a (which we arbitrarily add to myFst x) to illustrate that you can define intermediate values with let. The syntax is:

let bindings in expression

Everything defined in the let section is available inside the in expression, but not outside.

4. Why this matters

5. A playful mental model

Think of pattern matching as “cutting open” your data, recursion as “peeling through the list one layer at a time,” and let as “taking notes along the way.” Each tool builds a different piece of Haskell’s elegant simplicity.

6. Wrap-up

Our little “extract the sides” exercise might seem arbitrary, but it’s a perfect excuse to explore three of Haskell’s most important ideas. Once you’re comfortable with these, you’ll find yourself using them everywhere—pattern matching for data access, recursion for iteration, and let or where for organizing logic cleanly.



Comment


Not that much comments



Next