{-# LANGUAGE RankNTypes #-}
module Overview where 

-- Function declarations
plusone :: Int -> Int 
plusone x = x + 1

-- Polimorphism
first :: (a,b) -> a 
first (x,_) = x

-- Lists
lst1 = [1,2,3,4] 
lst2 = 5 : []
lst3 = lst1 ++ lst2

-- User-defined data types
data Nationality = Argentinian | Swedish

f :: Nationality -> String
f Argentinian = "Asado"
f Swedish   = "Surströmming"
 
data Tree a = Leaf | Node a (Tree a) (Tree a)

nodes :: Tree a -> [a]
nodes Leaf           = []
nodes (Node a t1 t2) = a : (nodes t1 ++ nodes t2)

-- Type classes
bcmp :: forall a. (Eq a) => a -> a -> Bool
bcmp x y = x == y 

-- IO 

hello :: IO ()
hello = do putStrLn "Hello! What is your name?"
           name <- getLine 
           putStrLn $ "Hi, " ++ name ++ "!" 

-- Monad IO

c :: IO ()
c = do name <- getLine 
       putStrLn $ "Hi, " ++ name ++ "!" 


-- Very inneficient function to compute the next prime number
nextPrime :: Int -> Int 
nextPrime n = head [ p | p <- primes, p >= n] 

primes :: [Int]
primes = sieve [2..]
   where
    sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]  

toInt :: String -> Int
toInt x = read x :: Int

prim :: IO (Int,Int)
prim = do number <- getLine 
          let n = toInt number
          return (n, nextPrime n)

-- Quiz
quiz1 :: IO () 
quiz1 = do putStrLn "What day were you born?"
           (n, np) <- prim 
           if n == np 
              then putStrLn $ "It is a prime number!"
              else putStrLn $ "Not interesting."