Skip to content

Introduction to Haskell

Bernard Sibanda edited this page Sep 19, 2024 · 1 revision

Introduction to Haskell

Haskell is a purely functional programming language that emphasizes immutability, strong static typing, and lazy evaluation. It's known for its mathematical precision, which makes it popular for writing reliable, maintainable, and error-free code. Haskell's core idea is that functions are the primary building blocks of the program, and the behavior of the program is derived by applying these functions.

Key Concepts:

  1. Pure Functions: Haskell functions do not have side effects (like modifying a global variable or printing output to the screen).
  2. Immutability: Once a value is defined, it cannot be changed.
  3. Lazy Evaluation: Haskell doesn’t compute values until they are absolutely needed, allowing for efficient computation.
  4. Strong Static Typing: Haskell has a strong type system, which means types are checked at compile time, helping catch errors early.

Simple Haskell Examples

1. Basic Hello World

A simple function that prints "Hello, World!".

main :: IO ()
main = putStrLn "Hello, World!"
  • main: This is the entry point of the program.
  • putStrLn: A built-in function that prints a string to the terminal.
  • :: IO (): Declares that main is an I/O action that doesn’t return a meaningful value.

2. Basic Arithmetic

Haskell can be used as a simple calculator. Here's how basic operations work:

add :: Int -> Int -> Int
add x y = x + y

main = print (add 5 3)  -- Output: 8
  • add is a function that takes two integers (Int) and returns their sum.
  • x + y: The function body, which adds two numbers.

3. Recursion (Factorial)

Recursion is very common in Haskell. Here’s an example of calculating a factorial using recursion.

factorial :: Int -> Int
factorial 0 = 1
factorial n = n * factorial (n - 1)

main = print (factorial 5)  -- Output: 120
  • Base case: When n is 0, the factorial is 1.
  • Recursive case: For n > 0, the factorial is calculated as n * factorial(n-1).

4. List Operations

Haskell excels in working with lists. Here’s an example of basic list manipulation:

doubleList :: [Int] -> [Int]
doubleList xs = map (*2) xs

main = print (doubleList [1, 2, 3, 4])  -- Output: [2, 4, 6, 8]
  • Lists are written as [1, 2, 3].
  • map (*2) xs: This applies the function (*2) (which doubles a number) to each element in the list xs.

5. Pattern Matching

Pattern matching is a powerful feature that simplifies the function definition based on different input patterns.

describeList :: [a] -> String
describeList [] = "The list is empty."
describeList [x] = "The list has one element."
describeList xs = "The list has more than one element."

main = print (describeList [1,2,3])  -- Output: "The list has more than one element."
  • This function matches the input list against different patterns like an empty list [], a list with one element [x], and any list xs.

6. Higher-Order Functions

Functions that take other functions as arguments or return functions are called higher-order functions.

applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)

main = print (applyTwice (+3) 10)  -- Output: 16
  • applyTwice: A function that takes another function f and applies it twice to the value x.

Haskell's Benefits:

  1. Conciseness: Haskell allows for writing short and expressive code.
  2. Safety: Strong typing reduces the risk of runtime errors.
  3. Mathematical Rigor: The language’s functional nature makes reasoning about code much easier, especially in complex systems.

Common Use Cases:

  • Academic Research: Haskell is often used in academia due to its mathematical precision.
  • Financial Software: Many financial systems use Haskell for its robustness and reliability.
  • Blockchain Development: As seen with Cardano's smart contract language, Plutus, which is based on Haskell.

This is just a starting point, but Haskell offers much more in terms of functional programming, strong typing, and abstraction capabilities.