-- Some small examples to introduce Haskell.
-- Functional Programming course 2018.
-- Thomas Hallgren

{-
This started as a skeleton, the function definitions were filled in
during the first lecture.
-}

import Test.QuickCheck
       
--------------------------------------------------------------------------------
-- * Currency conversion

exchangeRate = 10.316  -- SEK / EUR

toEUR sek = sek / exchangeRate

toSEK eur = eur * exchangeRate



prop_exchange eur = toEUR (toSEK eur) ~== eur

x ~== y = abs(x-y) < 1e-5

-- automated random testing with QuickCheck



--------------------------------------------------------------------------------
-- * Definition by cases

absolute x | x<=0      = -x
           | otherwise = x

absolute' x = if x<0 then -x else x



-- local definitions

--------------------------------------------------------------------------------
-- * Definition by recursion
-- The power function n^k

power :: Double -> Integer -> Double
power n 0        = 1
power n k | k>0  = n * power n (k-1)


prop_power n k = power n k' == n^k'
  where k' = abs k -- to avoid testing negative exponents

-- intersecting lines

intersect :: Integer -> Integer
intersect 0       = 0
intersect n | n>0 = (n-1) + intersect (n-1)

intersect' :: Int -> Int
intersect' n = sum [1 .. n-1]

--------------------------------------------------------------------------------
-- * Tuples

examplePair = (2,"Hello")

exampleTriple = (0,42,"Hello")

exampleFunction (b,n,s) = if b then show n else s

--------------------------------------------------------------------------------
-- * List

snacks = "Spam"

dinner = [snacks, "Fish", "Chips", snacks, snacks, "Pudding"]

summary :: [String] -> String
summary [] = "Nothing"
summary [x] = "Only "++x
summary [x,y] = x++" and "++y
summary (x:xs) = x++" then some more stuff, finally "++last xs

-- | Computing the length of a list
len :: [a] -> Integer
len [] = 0
len (_:xs) = 1 + len xs

last' []     = error "last': empty list"
last' [x]    = x
last' (x:xs) = last' xs

--------------------------------------------------------------------------------
-- * List comprehensions

ex1 = [ x*x | x<-[1..10] ]

doubles xs = [ 2*x | x<-xs ]

ex2 = [ x | x <- [1..20], odd x]

ex3 = [ (x,y) | x <- ['A'..'D'], y<-[1..4]]

ex4 = zip ['A'..'D'] [1..4]

pythag n = [(a,b,c) | a<-[1..n], b<-[a..n], c<-[b..n], a^2+b^2 == c^2]