Recitation 1

Bohan Jiang

2026-09-04

Logistics

  • About me
  • How the recitation works
  • Haskell setup
  • Haskell basics

About me

  • 2nd year CS PhD student
  • Email: bohanjiang@brandeis.edu
  • Office: Volen 110 (the cube at the top-right corner)
  • Office Hours: TBD

How the recitation works

  • Spend the first 3 labs for Haskell programming
  • The following recitations will mix Haskell and concepts
  • Review session for quiz

Haskell setup

Installation & setup

  1. Download GHCup in https://www.haskell.org/ghcup/
  2. Copy and run command starting with curl
  3. Confirm to install tools below:
    1. GHC: Haskell compiler
    2. cabal-install: tool for managing Haskell software
    3. Stack: program for developing Haskell projects
    4. language-server: Enable IDE features
  4. Once the installation completes, verify it by runnning
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 9.10.3

Interactive environment

Launch the environment by

$ ghci
GHCi, version 9.10.3: https://www.haskell.org/ghc/  :? for help

Simple arithmetic

ghci > 1 + 1
2

Print a string

ghci> putStrLn "Hello, world!"
Hello, world!

Define a function

ghci> double x = x + x
ghci> double 2
4

Haskell basics

What is Haskell?

Haskell is a programming language having following features:

  • Functions are first-class citizens
  • Evaluating expressions rather than execution instructions
  • Everything is immutable
  • Function is always evaluated to the same output given the same arguments
  • Expressions are not evaluated until their results are actually needed
take 5 [1..]
[1,2,3,4,5]
  • If not lazy, the evaluation would never consume the infinite list
  • Every expression has a type

Declarations and variables

  • We have below expressions

    x :: Int
    x = 3
  • :: is pronounced as “has type”

  • = is pronounced as “is defined to be”

  • Variable names must be in camelCase

Arithmetic & Boolean logic

  • Operators are functions, but they’re often expressed using infix notation
  • Common arithmetic operators are +, -, /, *, ^, mod etc.
  • Boolean logic operators are &&, ||, ==, /=, >, <, ... etc.
-- Infix notation
exInfix = 3 + 2
print exInfix

-- Function notation
exFunc = (+) 3 2
print exFunc
5
5

Types and Typeclasses

Type

  • A type can be understood as a “label” to an expression
  • Haskell would do type inference without knowing the value to define the exrpession
  • Haskell expresses a type using capital letter (e.g. String)
  • In ghci, execute :t on an expression to print out its type

Primitive types

  • Int: Machine-sized integers (\(\pm 2^{64}\) if your machine is 64-bit)
  • Float: single precision float
  • Char: unicode characters
  • Bool: boolen type
  • What is [Char]?

Type variables

  • If I use :t check a built-in function head
:t head
head :: forall a. HasCallStack => [a] -> a
  • a is a type variable, and it can be any type (generic type in other imperative languages)
  • Functions that have type variables are called Polymorphic functions

Typeclasses

  • A typeclass is an interface that defines some behavior
  • A type is a part of a typeclass
  • What does that mean?
    • The type supports and implements the behavior the typeclass describes
    • Similar to Java’s interface class

Typeclasses

  • As we know the arithmetic operator is a function, what’s the type for ==?
:t (==)
(==) :: forall a. Eq a => a -> a -> Bool

Eq typeclass

  • Eq is the typeclass, which provides an interface for testing for equality
    • All standard Haskell types except for IO and functions are a part of it
    • What does this remind you when you program python?
      • def __eq__(self, other)
  • => is called class constraint, which constrain the type variable a must be a member of the Eq class

Basic typeclasses

  • Eq
  • Ord: covers all the standard comparing functions (all types so far except for functions)
  • Show: members know how to represent strings (all types so far except for functions)
  • Read: knows how to interpret its textual representation
  • Enum: members can be sequentially ordered (i.e. enumerated)
  • Bounded: members have the lowest and the largest bounds
  • Num: members are numeric
  • Integral: members are whole numbers
  • Floating: members are floating point numbers

Define functions

Pattern match

  • The principle of constructing a function is pattern matching
  • Syntax
funcName :: typeA -> typeB
funcName <pattern1> = <value1>
funcName <pattern2> = <value2>
...
  • Each clause is checked from top to bottom until the first matching clause is chosen

Practice

  • Define a function called sayNum which takes an Int and yields String
sayNum :: Int -> String
sayNum 1 = "One"
sayNum 2 = "Two"

sayNum 2
"Two"

Recursion

  • Another way of constructing a function is recursion
  • Two expressions: base case AND recursive case
funcName :: typeA -> typeB
funcName <baseCase>
funcName <recursiveCase>

Practice

  • Define a function sumtorial which computes the sum of the integers from 1 to n
sumtorial :: Int -> Int
sumtorial 0 = 0
sumtorial n = n + sumtorial (n-1)

sumtorial 4
10

Guards

  • That is equivalent to choices can be made within a clause
  • A guard is expressed as a boolean expression
func :: typeA -> typeB
func <input>
  | <boolExpr1> = <value1>
  | <boolExpr2> = <value2>
  | ...
  | otherwise = <value>

Practice

  • Define a function relu that implements ReLU function where \(f(x) = max(0, x)\)
relu :: Float -> Float
relu n
  | n > 0 = n
  | otherwise = 0

relu 6.23
relu (-1.14)
6.23
0.0