## Computer Graphics in Haskell

# Welcome

- http://savanni.luminescent-dreams.com/static/presentations/haskell-graphics.html
- Software Engineer at EnergyCurb
- Twitter: @savannidgerinel
- savanni@luminescent-dreams.com
- Code witch, photographer, cyclist, agender, feminist, radical queer, general geek

# Functions

```
circleArea :: Float -> Float
circleArea r = pi * r ^ 2
rectangleArea :: Float -> Float -> Float
rectangleArea l w = l * w
triangleArea :: Float -> Float -> Float
triangleArea h b = h * b / 2
totalCirclesArea :: [Float] -> Float
totalCirclesArea rs = sum (map circleArea rs)
```

# Function Structure

```
functionName :: TypeParam1 -> TypeParam2 -> ... -> TypeResult
functionName param1 param2 ... =
```

# Functions

```
pi :: Float
```

# Functions

```
not :: Bool -> Bool
```

`not`

is a function which takes a single parameter (a Boolean) and returns a result (another Boolean).

# Functions

```
(++) :: String -> String -> String
```

`++`

is a function which takes one parameter (a String) and returns a new function that takes a single parameter (also a String) and returns a result.

# Functions

```
(++) :: String -> String -> String
> :t (++) "a"
(++) "a" :: String -> String
```

# Functions

```
(++) :: String -> String -> String
> :t (++) "a" "b"
(++) "a" "b" :: String
> (++) "a" "b"
"ab"
```

# Functions

```
(++) :: String -> String -> String
> :t (++) "a" "b"
(++) "a" "b" :: String
> (++) "a" "b"
"ab"
> "a" ++ "b"
"ab"
```

# Polymorphism

```
(++) :: [a] -> [a] -> [a]
```

`++`

is a function which takes one parameter (a list of anything) and returns a new function that takes a single parameter (also a list, but of the same thing) and returns a result. `++`

works on the list structure and cares nothing for the data contained in the list.

# Partial Application and more Polymorphism

```
map :: (a -> b) -> [a] -> [b]
```

Map is a function which takes one parameter (itself a function) and returns a new function that takes a single parameter and returns a result.

# Partial Application and more Polymorphism

```
map :: (a -> b) -> [a] -> [b]
> :t map not
map not :: [Bool] -> [Bool]
```

# Partial Application and more Polymorphism

```
map :: (a -> b) -> [a] -> [b]
> :t map not
map not :: [Bool] -> [Bool]
> :t map not [True, True, False]
map not [True, True, False] :: [Bool]
> map not [True, True, False]
[False,False,True]
```

# Type Constraints

```
show :: Show a => a -> String
> show 15
"15"
```

`show`

is a function that takes a value, which must implement the `Show`

interface, and returns a `String`

.

# Type Constraints

```
show :: Show a => a -> String
class Show a where
show :: a -> String
```

`show`

is a function that takes a value, which must implement the `Show`

interface, and returns a `String`

.

# Building polymorphism

```
circleArea :: Float -> Float
circleArea r = pi * r ^ 2
rectangleArea :: Float -> Float -> Float
rectangleArea l w = l * w
triangleArea :: Float -> Float -> Float
triangleArea h b = h * b / 2
totalCirclesArea :: [Float] -> Float
totalCirclesArea rs = sum (map circleArea rs)
```

# Building polymorphism

```
area :: ??? -> Float
totalArea :: [???] -> Float
totalArea shapes = sum (map area shapes)
```

# Defining a data type

- Int
- Float
- String

# Defining a data type

```
data Shape = ...
deriving (Show)
```

# Defining a data type

```
data Shape = Circle
deriving (Show)
Shapes> let a = Circle
Shapes> a
Circle
Shapes> :t a
a :: Shape
Shapes> :t Circle
Circle :: Shape
```

# Add a radius to the Circle

```
data Shape = Circle Float
deriving (Show)
Shapes> :t Circle
Circle :: Float -> Shape
Shapes> let a = Circle 15
Shapes> a
Circle
Shapes> :t a
a :: Shape
```

# Python Equivalent

```
class Shape:
def __init__ (self, name, *args):
self.shape = name
self.args = args
@classmethod
def Circle (cls, radius):
return cls("Circle", radius)
```

# Add a few more shapes

```
data Shape = Circle Float
| Rectangle Float Float
| Triangle Float Float
deriving (Show)
Shapes> :t Circle 15
Shape
Shapes> :t Rectangle 15.0 16.0
Shape
```

# Python Equivalent

```
class Shape:
def __init__ (self, name, *args):
self.shape = name
self.args = args
@classmethod
def Circle (self, radius):
return cls("Circle", radius)
@classmethod
def Rectangle (self, length, width):
return cls("Rectangle", length, width)
@classmethod
def Triangle (self, height, base):
return cls("Triangle", height, base)
```

# Destructuring

```
area :: Shape -> Float
area (Circle ...) = ...
area (Rectangle ...) = ...
area (Triangle ...) = ...
```

# Destructuring

```
area :: Shape -> Float
area (Circle r) = pi * r ^ 2
area (Rectangle l w) = l * w
area (Triangle b h) = b * h / 2
```

# Destructuring

```
area :: Shape -> Float
area (Circle r) = pi * r ^ 2
area (Rectangle l w) = l * w
area (Triangle b h) = b * h / 2
totalArea :: [Shape] -> Float
totalArea shapes = sum (map area shapes)
```

# Seen in action

```
*Shapes> map area [Circle 1, Rectangle 1 1, Triangle 1 1]
[3.1415927,1.0,0.5]
*Shapes> map area [Circle 15, Rectangle 14 20, Triangle 15 16]
[706.85834,280.0,120.0]
```

# Let’s switch to graphics

# Gloss

```
display :: Display -> Color -> Picture -> IO ()
```

# Gloss Pictures

```
data Picture = Circle Float
| Polygon Path
| Blank
display (InWindow "Women Who Code" (200, 200) (10, 10)) black (Circle 80)
```

# Gloss Pictures

```
data Picture = Circle Float
| Polygon Path
| Blank
| Color Color Picture
display (InWindow "Women Who Code" (200, 200) (10, 10)) black (Color white (Circle 80))
```

# Gloss Pictures

```
data Picture = Circle Float
| Polygon Path
| Blank
| Color Color Picture
| Pictures [Picture]
display (InWindow "Women Who Code" (200, 200) (10, 10))
black
(Pictures [ Color white (Circle 80)
, Color blue (Circle 40)
] )
```

# Gloss Pictures

```
data Picture = Circle Float
| Polygon Path
| Blank
| Color Color Picture
| Pictures [Picture]
| Translate Float Float Picture
| Rotate Float Picture
| Scale Float Float Picture
display (InWindow "Women Who Code" (200, 200) (10, 10))
black
(Pictures [ Color white (Translate 15 0 (Circle 80))
, Color blue (Circle 40)
] )
```