1
1
module Exercises where
2
2
3
3
import Prelude
4
+ import Data.Maybe (Maybe (Just, Nothing))
5
+ import Data.Picture (Point (..), Shape (..))
6
+ import Math (pow , pi )
4
7
5
8
-- Not stack safe (crashes with large inputs).
6
9
factorial' :: Int -> Int
@@ -14,12 +17,55 @@ factorial n = fact' n 0 where
14
17
fact' 0 acc = acc
15
18
fact' n acc = fact' (n - 1 ) (acc + n)
16
19
17
- -- This is not stack safe - due to double recursion tail call optimisation
18
- -- is not possible. Although the exercise asks us to implement this algorithm
19
- -- specifically, an entirely different approach would be required to make this
20
- -- function safe.
20
+ {-
21
+ This is not stack safe - due to double recursion tail call optimisation
22
+ is not possible. Although the exercise asks us to implement this algorithm
23
+ specifically, an entirely different approach would be required to make this
24
+ function safe.
25
+ -}
21
26
binomial :: Int -> Int -> Int
22
27
binomial 0 n = 1
23
28
binomial k 0 = 0
24
29
binomial k n | k == n = 1
25
30
| otherwise = (binomial (k - 1 ) (n - 1 )) + (binomial k (n - 1 ))
31
+
32
+ -- Pattern matching on records.
33
+ type Address = { street :: String , city :: String }
34
+ type Person = { name :: String , address :: Address }
35
+
36
+ sameCity :: Person -> Person -> Boolean
37
+ sameCity { address: { city: x }} { address: { city: y }}
38
+ | x == y = true
39
+ | otherwise = false
40
+
41
+ -- Pattern matching on arrays.
42
+ fromSingleton :: forall a . a -> Array a -> a
43
+ fromSingleton d [x] = x
44
+ fromSingleton d _ = d
45
+
46
+ -- Algebraic Data Types.
47
+ origin :: Point
48
+ origin = Point { x: 0.0 , y: 0.0 }
49
+
50
+ myCircle :: Shape
51
+ myCircle = Circle origin 10.0
52
+
53
+ scaleAndCentre :: Shape -> Shape
54
+ scaleAndCentre (Circle _ r) = Circle origin (r * 2.0 )
55
+ scaleAndCentre (Rectangle _ w h) = Rectangle origin (w * 2.0 ) (h * 2.0 )
56
+ scaleAndCentre (Line (Point start) (Point end)) = Line transformStart transformEnd where
57
+ xdiff = start.x - end.x
58
+ ydiff = start.y - end.y
59
+ transformStart = Point { x: -xdiff, y: -ydiff }
60
+ transformEnd = Point { x: xdiff, y: ydiff }
61
+ scaleAndCentre (Text _ str) = Text origin str
62
+
63
+ extractString :: Shape -> Maybe String
64
+ extractString (Text _ str) = Just str
65
+ extractString _ = Nothing
66
+
67
+ -- Vector graphics library.
68
+ area :: Shape -> Number
69
+ area (Circle _ r) = pi * (pow r 2.0 )
70
+ area (Rectangle _ w h) = w * h
71
+ area _ = 0.0
0 commit comments