import Data.List (sort) -------------------- -- Exercise 1 -------------------- data Car = Car { model :: Model , make :: Make , year :: Integer , color :: Color , power :: Horsepower } deriving (Show, Eq, Ord) ---------- -- a) ---------- newtype Model = Model String deriving (Show, Eq, Ord) newtype Make = Make String deriving (Show, Eq, Ord) data Color = RGB { r :: Integer , g :: Integer , b :: Integer } deriving (Show, Eq, Ord) type Horsepower = Integer ---------- -- b) ---------- ford = Car { make = Make "Ford", model = Model "Fiesta", color = RGB { r = 0xFF, g = 0x00, b = 0x00 }, power = 70, year = 2017 } ferrari = Car { make = Make "Ferrari", model = Model "Testarossa", color = RGB 0x00 0xFF 0x00, power = 27, year = 1991 } zoe = Car { make = Make "Renault", model = Model "Zoe", color = RGB 0xFF 0xFF 0xFF, power = 70, year = 2023 } sorted = sort [zoe, ferrari, ford] -- >>> sorted -- [Car {model = Model "Fiesta", make = Make "Ford", year = 2017, color = RGB {r = 255, g = 0, b = 0}, power = 70},Car {model = Model "Testarossa", make = Make "Ferrari", year = 1991, color = RGB {r = 0, g = 255, b = 0}, power = 27},Car {model = Model "Zoe", make = Make "Renault", year = 2023, color = RGB {r = 255, g = 255, b = 255}, power = 70}] -------------------- -- Exercise 2 -------------------- data Tree a = Node (Tree a) a (Tree a) | Leaf a ---------- -- a) ---------- collect :: Tree a -> [a] collect x = case x of Node a b c -> [b] ++ concat (map collect [a, c]) Leaf a -> [a] ---------- -- b) ---------- data PolyTree a = PolyTree a [PolyTree a] deriving (Show) ---------- -- c) ---------- tree = PolyTree 1 [ PolyTree 2 [ PolyTree 5 [], PolyTree 6 [], PolyTree 7 [] ], PolyTree 3 [ PolyTree 8 [] ] ] -- >>> show tree -- "PolyTree 1 [PolyTree 2 [PolyTree 5 [],PolyTree 6 [],PolyTree 7 []],PolyTree 3 [PolyTree 8 []]]" -------------------- -- Exercise 3 -------------------- data NatNumber = Z | S NatNumber deriving (Show) eval :: NatNumber -> Integer eval x = case x of Z -> 0 S a -> 1 + eval a -- >>> Z -- Z -- >>> eval (S (S (S Z))) -- 3 uneval :: Integer -> NatNumber uneval x | x < 0 = error "negative numbers are not natural numbers" | x == 0 = Z | otherwise = S (uneval (x - 1)) -- >>> uneval (-1) -- negative numbers are not natural numbers -- >>> uneval 0 -- Z -- >>> uneval 1 -- S Z -- >>> uneval 3 -- S (S (S Z)) addNat :: NatNumber -> NatNumber -> NatNumber addNat a b = case (a, b) of (Z, b) -> b (S a, b) -> S (addNat a b) -- >>> eval (addNat (uneval 7) (uneval 2)) -- 9 mulNat :: NatNumber -> NatNumber -> NatNumber mulNat a b = case (a, b) of (Z, b) -> Z (S a, b) -> addNat (mulNat a b) b -- >>> eval (mulNat (uneval 3) (uneval 2)) -- 6 fact :: NatNumber -> NatNumber fact x = case x of Z -> S Z S a -> mulNat (S a) (fact a) -- >>> eval (fact Z) -- 1 -- >>> eval (fact (S (S Z))) -- 2 -------------------- -- Exercise 3 -------------------- type Program = [(Integer, Integer)] type Input = Integer type Output = [Integer] execute :: Program -> Input -> Output execute program input = reverse (internal program input []) where internal :: Program -> Input -> Output -> Output internal [] input output = input:output internal ((a,b):coefficients) input output | mod (input * a) b == 0 = internal program (div (input * a) b) (input:output) | otherwise = internal coefficients input output fibProgram :: Program fibProgram = [ (91,33) , (11,13) , (1,11) , (399,34) , (17,19) , (1,17) , (2,7) , (187,5) , (1,3) ] -- Should evaluate to True -- >>> sum (execute fibProgram 31250) == 26183978971946924 -- True