# Programming Languages

### Datatypes & IO

Jim Posen - ECE/CS 2014

## Last time on Programming Languages

• We discussed Haskell’s static type system
• Values in Haskell have types
• Haskell infers the types of values
• Types have typeclasses
• Functions have types

# Let’s make some types

## Types in other languages

• Object oriented languages allow you to create types
• In OOP, classes define types
• In C, you can use structs and unions

## What types have we seen?

• Bool, Char, Int, Float, Integer, Double
• Often these are “primitives” in other languages

## Let’s look at Bool

• A Bool is either True or False
``````data Bool = False | True
``````

## Points

• We want a datatype for a point in the 2D plane
``````data Point = Point Float Float
``````

### What does that do?

• Given two Floats, we can create a Point
``````let x = Point 3.0 4.0 :: Point
``````

## Shape Types

• There are some operations we want to do on 2D shapes
• Let’s just consider Rectangles

## Circles

• A Circle can be defined by a center and a radius
``data Shape = Circle Point Float``

## Rectangles

• But a rectangle is also a shape
• A rectangle can be defined by the top left corner and the bottom right corner
``````data Shape = Circle Point Float | Rectangle Point Point
``````

## Datatypes

• A datatype has one or more constructors
• An value of a datatype is built with one of the constructors
• The value has each of the required parameters

## Constructors

• Constructors are just functions
• Constructors take arguments and return a value of a datatype
``````ghci> :t Point
Point :: Float -> Float -> Point
``````

Constructors can be partially applied

``````ghci> let points = map (Point 0) [1 2 3]
``````

Why doesn’t this work?

``````Prelude> map (Point 1) [0, 2, 3]
:7:1:
No instance for (Show Point) arising from a use of `print'
Possible fix: add an instance declaration for (Show Point)
In a stmt of an interactive GHCi command: print it
``````

## Typeclasses again

• Point needs typeclass Show
• `deriving` keyword used to give typeclasses to datatypes
``````data Point = Point Float Float deriving (Show)
``````

## Operating on Datatypes

How do we compute the area of a Shape?

``````area :: Shape -> Float
area s = ...
``````

Pattern matching to the rescue!

``````area :: Shape -> Float
area (Circle center radius) = pi * r ^ 2
area (Rectangle (Point x1 y1) (Point x2 y2)) = (abs \$ x2 - x1) * (abs \$ y2 - y1)
``````

## Case Expressions

• Sometimes you can’t easy pattern match in the function declaration
• Case statement performs pattern matching
• ``````myFavoriteShape :: Shape
...

doILikeCircles =
case myFavoriteShape of
Circle _ _ -> True
Rectangle _ _ -> False
``````

## Let’s model a Person

• A person has a first name, last name, phone number, email address, age, and height
``````data Person = Person String String String String Int Float
``````

### How do we get a person’s age?

``````age :: Person -> Int
age (Person _ _ _ _ a _) = a
``````

Oh hell no. This is bad.

## Record Syntax

• Special syntax for named constructor parameters
• You don’t need to remember the order of parameters
• Haskell generates getter functions for you
``````ghci> data Person = Person {
firstName :: String,
lastName :: String,
phoneNumber :: String,
age :: Int,
height :: Float
} deriving (Show)

ghci> let chuck = Person {
firstName = "Chuck",
lastName = "Norris",
phoneNumber = "(123) 456-7890",
age = -5,
height = 200
}
ghci> height chuck
200
``````

## Recursive Data Types

• Recursive data types are often very useful
• Let’s make a tree of Ints
``````data Tree = EmptyTree | Node Int Tree Tree
``````

## Polymorphic Data Types

• Sometimes we want general types
• Say we want a Tree of Chars or any other type
• We want to construct a new type for each type of Tree
• Think of generics in Java, but better

Instead of defining a type, we define a Type constructor

``````data Tree a = EmptyTree | Node a (Tree a) (Tree a)
``````

One caveat: `Tree` is NOT a type, it is a type constructor

This is an invalid type declaration

``````insert :: a -> Tree -> Tree
``````

This is correct

``````insert :: a -> Tree a -> Tree a
``````

## Lists

• Let’s make a Lisp-style linked list
• A list is either nil or a (cons a b)
``data List a = Nil | Cons a (List a)``

## Mind blowing slide 2

• The lists we have been using all along are just syntactic sugar for this type of list
• `Nil => []`
• `Cons x xs => (x:xs)`
• `Cons x Nil => [x]`
• The reason list pattern matching works is because pattern matching with this data type works

# Input/Output

## How does Haskell do IO?

• Programs are useless without IO
• Without IO, everything can be computed at compile time
• However, IO is a side effect

## Side effects revisited

• Recall the definition of referential transparency
• A function applied to some arguments can be replaced by its value
• What is the behavior of `getLine` and `putStrLn` ?

### Input

If we try to declare `getLine :: String` it must always return the same string

This is not what we want

### Output

If we try to declare `putStrLn :: String -> ()` it is not referentially transparent as it has a side effect

## IO Witchcraft

• Haskell’s way around this is to use the IO type constructor
• An IO String is an object that contains a string
• How do we get the value out of an IO?
• Pattern matching will not work

## A Simple Greeting Program

``````greet :: IO ()
greet = do
putStr "What is your name? "
name <- getLine
putStrLn \$ "Hi " ++ name ++ "!"
return ()
``````

### What is an IO ()?

It’s a () wrapped in an IO

### What is an IO String?

It’s a String wrapped in an IO

This may be a bit more useful

``````greet :: IO String
greet = do
putStr "What is your name? "
name <- getLine
putStrLn \$ "Hi " ++ name ++ "!"
return name
``````

## Return (to a time before you knew what return was)

• `return` in Haskell is unlike any other return you have seen before
``````ghci> :t return
return :: Monad m => a -> m a``````

That’s scary.

• All return does is takes an a and returns an IO a
• `return` wraps an object in an IO
• The last statement in your `do` block is the return value of the function

What does this do?

``````helloWorld :: IO ()
helloWorld = do
return ()
putStrLn "Hello World!"
``````

## The main function

• Compiled Haskell programs execute the `main` function
• ``````main :: IO ()
main = ...``````