-- CSC 330 Programming Languages - Some Haskell code
-- Check www.haskell.org for more details 
-- I have tried this code using the hugs 
-- interpreter. The hugs interpreter only 
-- allows to type expressions not declarations. 
-- The declarations can be load by typing 
--  :load test.hs 
-- (the : character is important and test.hs 
-- is the name of a file with the function and value 
-- declarations 

-- Simple function and variable declarations 
simple x y z = x * (y + z)
r1 = 5.0;
r2 = 2.0;
r3 = 3.0;

--  Function to compute the area of a circle 
circleArea :: Double->Double 
circleArea r = pi * r ^ 2

-- Sum of list items ---
listSum :: [Double]->Double 
listSum [] = 0
listSum (x:xs) = x + listSum xs 

-- Our friend the map function 
mymap f [] = [] 
mymap f (x:xs) = f x:map f xs 

totalArea = listSum[circleArea r1, circleArea r2, circleArea r3]
totalArea1 = mymap circleArea [r1,r2,r3]
x = mymap (\(a,b)->a+b) [(1,2),(2,5),(3,4),(4,6)]


-- Quick sort in haskell 
quicksort  []           =  []
quicksort (x:xs)        =  quicksort [y | y <- xs, y<x ]
                        ++ [x]
                        ++ quicksort [y | y <- xs, y>=x]


-- Infinte lists  - A cool (and efficient) definition of Fib 

fib             = 1 : 1 : [ a+b | (a,b) <- zip fib (tail fib) ]

first100 = take 100 fib


-- Qualified types 
-- Rather than "for all types a" we can say 
-- "for all types a that are members of class C" 
-- For more details look on the web. Therefore 
-- in haskell we can overload a symbol like + or - 
-- to work for any type of data we wish 


square x = x * x


-- Sieve of Eratosthenes 
sieve (x:xs) = x : sieve [ n | n <- xs, mod n x /= 0] 
primes = sieve [2..] 

val hundredPrimes = take 100 primes 
