content: --EDAN40 tenta 17.12.2012
  
  -- QUESTION 1
  -- point-free form
  
  -- f x y = 3 + y / x
  h = flip (/)
  g = (3.0+) -- to take care of fractional results of h
  -- we would like something like f = g . h
  -- but we need to take care of both args to (/), so
  f = curry (g . (uncurry h))
  -- or, without help functions
  f1 = curry ((3.0+) . (uncurry (flip (/))))
  -- or, eg.
  f2 = curry $ (3.0+) . (uncurry  $ flip (/))
  -- to skip some brackets
  
  -- g x y = [y z | z <- [1..x]]
  h1 = flip take $ iterate (+1) 1
  h2 = flip map 
  g = h2 . h1
  -- or, without help functions
  g1 = flip map . (flip take $ iterate (+1) 1)
  
  
  -- QUESTION 2
  -- types
  
  (.)(:) :: (a -> b) -> a -> [b] -> [b]
  -- (:(.)) type error
  ((.):) :: [(b -> c) -> (a -> b) -> a -> c] -> [(b -> c) -> (a -> b) -> a -> c]
  ((:):) :: [a -> [a] -> [a]] -> [a -> [a] -> [a]]
  (.)(.) :: (a -> b -> c) -> a -> (a1 -> b) -> a1 -> c
  
  -- QUESTION 3
  -- spark, seq, pseq, par (Lecture 10, Parallelism)
  
  -- Spark: a potential to create a thread
  seq, pseq, par :: a -> b -> b
  -- seq: suggests evaluation of its first arg (up to WHNF), returns the second
  -- pseq: forces evaluation of the first arg first, then returns the second
  -- par: like seq, but evaluation of the first arg may be done in parallel with returning the second
  
  -- QUESTION 4
  -- fmap, do, bind
  fmap :: Functor f => (a -> b) -> f a -> f b
  -- m is a monadic object (a list, a Maybe, ...)
  
  fmap f m = do x <- m 
                return (f x)
  -- translate into bind
  fmap f m = m >>= \x -> return (f x)
  -- or
  fmap f m = m >>= (return . f)
  
  -- QUESTION 5
  -- equivalence of two list comprehensions
  
  -- result-wise YES
  -- computation-wise NOT NECESSARILY, but possibly
  
  -- QUESTION 6
  -- define Tree type, keeping String values in all nodes
  -- define predicate subTree t1 t2
  
  -- a binary tree case. Can be done differently, of course
  
  data Tree = Leaf String | Node Tree String Tree
  
  subTree :: Tree -> Tree -> Bool
  subTree (Leaf s) t = inTree s t
  subTree (Node t1 s1 t2) (Leaf s2) = False
  subTree (Node t1 s1 t2) (Node t3 s2 t4) = 
     ((s1 == s2) && (subTree t1 t3) && (subTree t2 t4)) ||
     subTree (Node t1 s1 t2) t3 ||
     subTree (Node t1 s1 t2) t4
  
  inTree :: String -> Tree -> Bool
  inTree s1 (Leaf s2) = (s1 == s2)
  inTree s1 (Node t1 s2 t2) = (s1 == s2) || inTree s1 t1 || inTree s1 t2
  