Polymorphism, type classes, maybe, either

Class: CSCE-314


Notes:

Knowledge Check 4

1. Introduction: Why Do We Need Polymorphism and Type Classes?

2. Polymorphism in Haskell

Haskell functions are polymorphic by default if they don’t require special operations.

Example:

length :: [a] -> Int  

Another example:

identity :: a -> a  
identity x = x  

Teaching point (benefit): polymorphism increases code reuse and reduces redundancy.

3. Type Classes: Eq, Ord, Show

A type class in Haskell is like an interface — it defines a set of functions that a type must implement.

Common built-in type classes:

Eq: for equality (==, /=).  
(==) :: Eq a => a -> a -> Bool

Only works on types that are members of the Eq type class.

Ord: for ordering (<, >, <=, >=, compare).
(<) :: Ord a => a -> a -> Bool

Show: for converting values to strings (so they can be printed).

show :: Show a => a -> String

Example:

isEqual :: Eq a => a -> a -> Bool
isEqual x y = x == y
maxOfTwo :: Ord a => a -> a -> a
maxOfTwo x y = if x > y then x else y

4. Combining Polymorphism and Type Classes

Example:

describe :: (Eq a, Show a) => a -> a -> String
describe x y = if x == y then "They are equal: " ++ show x else "They are different: " ++ show x ++ " vs " ++ show y

5. Error Handling with Maybe

Sometimes a function might fail or not return a result.

In many languages, this causes a runtime error. In Haskell, we can model this with Maybe.

data Maybe a = Nothing | Just a

Example: safe division:

safeDiv :: Int -> Int -> Maybe Int
safeDiv _ 0 = Nothing
safeDiv x y = Just (x `div` y)

Example: safe head of a list:

safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x

Teaching point: Maybe makes failure explicit in the type signature

6. Error Handling with Either

Either is like Maybe, but gives more information about what went wrong.

data Either l r = Left l | Right r

Example:

safeDivMsg :: Int -> Int -> Either String Int
safeDivMsg _ 0 = Left "Division by zero!"
safeDivMsg x y = Right (x `div` y)

Either is useful when we want to return not only success/failure but also an error message.

7. Summary

Polymorphism: write functions that work across types (e.g., length :: [a] -> Int).

Type classes: restrict polymorphism to types with specific capabilities (Eq, Ord, Show).

Maybe/Either: handle errors safely without crashing, by encoding failure into the type system.

Next time (Wednesday), we’ll practice by writing polymorphic functions with type class constraints, and Friday we’ll apply this to build a dictionary with safe lookups using Maybe.

Takeaway: Many ideas are universal in FP, Haskell provides its own tools for you.