-- | Some small examples to introduce Haskell.
-- Functional Programming course 2016.
-- Thomas Hallgren
{-
This started out as a skeleton, the function definitions were filled in
during the first lecture.
-}
import Test.QuickCheck
-- * Currency conversion
exchangeRate = 9.8963 -- SEK / EUR
toEUR :: Double -> Double
toEUR sek = sek / exchangeRate
toSEK :: Double -> Double
toSEK eur = eur * exchangeRate
prop_exchange sek = toSEK (toEUR sek) ~== sek
x ~== y = abs (x-y) < 2e-10
-- automated random testing with QuickCheck
-- * Definition by cases
{-
absolute x | x<0 = -x
absolute x | x>=0 = x
-}
absolute2 x | x<0 = -x
| x>=0 = x
absolute1 x = if x<0 then -x else x
-- * Definition by recursion
-- The power function n^k
power :: Integer -> Integer -> Integer
power n 0 = 1
power n k | k>0 = power n (k-1) * n
--power n k | k<0 = 1 / power n (-k)
prop_power n k = k >= 0 ==> power n k == n^k
-- intersecting lines
intersect 0 = 0
intersect k | k>0 = intersect (k-1) + k - 1
-- * Tuples
examplePair :: (Bool, Double)
examplePair = (True, 3.14)
exampleTriple :: (Bool, Int, String)
exampleTriple = (False, 42, "Answer")
exampleFunction :: (Bool, Int, String) -> Int
exampleFunction (b,n,s) = if b then n else length s
-- * List
snacks = "Spam"
dinner = [snacks, "Fish", "Chips", snacks, snacks, "Pudding"]
summary :: [String] -> String
summary [] = "Nothing"
summary [x,y] = x ++ " and " ++ y
summary (x:y:xs) = x ++ " and something else, finally " ++ last xs
-- | Computing the length of a list
len [] = 0
len (x:xs) = 1 + len xs
last' [] = error "last of empty list"
last' [x] = x
last' (x:xs) = last' xs
-- * List comprehensions
ex1 = [ x | x<-[1..20], even x]
doubles xs = [ 2*x | x<-xs ]
ex2 = [[x,y] | x<-"ABC", y<-"12"]
ex3 = [[[x,y] | y<-"12"] | x<-"ABC"]
pythag n = [(a,b,c) | a <- [1..n], b<-[a..n], c<-[b..n], a^2 + b^2 == c^2]