-- code_2009_02_25.hs
-- Glenn G. Chappell
-- 25 Feb 2009
--
-- For CS 331 Spring 2009
-- Sample Haskell code
-- From the Wednesday, February 25, 2009 class meeting


-- ---------------------------------------------------------------------
-- Code from topic Haskell: Basics
-- ---------------------------------------------------------------------


-- Define your own operators
x ++&^%# y = x*y + 2
-- You can also set precedence and associativity


-- fibo_a
-- Fibonacci number computation
-- the SLOW recursive way
fibo_a 0 = 0
fibo_a 1 = 1
fibo_a n = fibo_a (n-2) + fibo_a (n-1)


-- fibo_b
-- Fibonacci number computation
-- a faster way. Uses helper function fibpair: recursive, returns pair.
fibo_b n = snd (fibpair n) where
    fibpair 0 = (1, 0)
    fibpair n = (b, a+b) where
        (a, b) = fibpair (n-1)


-- fibo_c
-- Fibonacci number computation
-- recursive memoizing
fibo_c 0 = 0
fibo_c 1 = 1
fibo_c n = fibs !! (n-2) + fibs !! (n-1)

fibs = [fibo_c n | n <- [0..]] -- List of ALL Fibonacci numbers!
                               -- Lazy evaluation RULEZ!!!!1!1!1
-- Type
--     take 100 fibs
-- to see the first 100 Fibonacci numbers.


-- About currying
add x y = x + y
-- It *looks* like function add takes 2 params and returns a number.
-- Nope. It takes 1 param and returns a function.
-- For example:
addThree = add 3
-- Now addThree 2 is 5.
-- That is, (add 3) 2 is 5.
-- In other words, add 3 2 is 5, just as it should be.


-- ---------------------------------------------------------------------
-- Code from topic Haskell: Lists & Loops
-- ---------------------------------------------------------------------


-- Pattern matching
hd (x:xs) = x   -- returns first item in nonempty list ("head")
tl (x:xs) = xs  -- returns rest of nonempty list ("tail")
-- Note the "x:xs" idiom

