206 lines
3.9 KiB
Haskell
206 lines
3.9 KiB
Haskell
|
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
|