-- Erste Beispiele in Haskell
-- 
-- Jost Berthold, FB 12
-- Philipps-Universität Marburg
-------------------------------

{- Kommentare mit "--" bis Zeilenende oder
  mit "{ und -" in mehreren Zeilen -}

-- einzeiliger Kommentar

{- mehrzeiliger Kommentar...
  Diese Kommentare können geschachtelt werden:
  {- Dies ist ein Kommentar auf Ebene 2,
    der sich über zwei Zeilen erstreckt...
  -} 
  Dies ist ein Kommentar auf  Ebene 1, der 
  Ebene, auf der sich auch "mehrzeiliger Kommentar..." 
  befindet! -}

-- Die Datei soll ein Modul "Simple" definieren, das 
-- hinterher in andere Dateien importiert werden kann.
module FirstHaskell
-- hier können wir explizit festlegen, was nach außen exportiert wird:
-- nichts angeben => alles wird exportiert.
  (add, square, simple, eps)
  where
-- hier gehen die Definitionen los:

-- Funktionen
add x1 x2 = x1 + x2
square x  = x * x
simple a b c = a*( b+c )

-- x hoch 4, mit der square-Funktion
powerfour x = square x * square x


-- Konstanten, Typen
newline = '\n'
eps  = 0.000001

lessEqualEps x = (x <= eps)

-- Aufruf "lessEqualEps eps' führt zu Typfehler!!!

-- explizite Typangabe bei Funktionen:
simple2 :: Int -> Int -> Int -> Int
simple2 a b c = a * ( b + c )


------------------------------------------------------------
-- Die "main"-Funktion beschreibt, was ein *übersetztes* Programm 
-- tun würde, genauso wie Java's "main" Methode von Objekten

-- hier allerdings absichtlich mit Typfehler, daher auskommentiert
 
--main = print (simple2 newline 42 "abc")
 
-----------------------------------------


-- weitere Syntax: 

-- lokale Definitionen und Layout, "Guards" für Fallunterscheidung
zinseszins :: Double -> Double -> Int -> Double
zinseszins   zinssatz   summe   jahre  
     | jahre == 0 = summe
     | jahre >  0 = let
		       erstesJahr = summe * faktor
		       faktor     = 1 + (0.01 * zinssatz )-- Test: fehlende ')'
		    in zinseszins zinssatz erstesJahr (jahre - 1) 
     | otherwise = error "Jahre negativ"

-- hier: Rechnung "Faktor hoch Jahre" geht nur mit Typkonvertierung
zinseszins2 :: Double -> Double -> Int -> Double
zinseszins2 zinssatz summe jahre | jahre < 0 = error "Jahre negativ"
                                 | otherwise = summe * faktor ** dbljahre
        where 
	   faktor   = 1 + (0.01 * zinssatz)
           dbljahre = fromInt jahre -- Test: falsche Einrückung
