Skip to content
Snippets Groups Projects
Aufgabe1.hs 5.22 KiB
Newer Older
  • Learn to ignore specific revisions
  • Nicole Dresselhaus's avatar
    Nicole Dresselhaus committed
    -- Aufgabe 1
    -- =========
    
    module Aufgabe1 where  
    
    import AdressSys  
    
    
    -- Applicative style – an abstract pattern for everyday use. 
    -- --------------------------
    -- 
    -- Wiederholung: 
    -- -----------------------------------
    -- (<$>) ::   (a -> b)   -> f a -> f b
    -- (<*>) :: f (a -> b)   -> f a -> f b
    -- (=<<) ::   (a -> m b) -> m a -> m b  -- (=<<) == flip (>>=)
    -- -----------------------------------
    -- 
    -- Aus der Vorlesung wissen Sie bereits, dass `[]` und `Maybe` `Applicative`s sind und 
    -- dass `Applicative` ermöglicht, 'Funktionen im Kontext' auf Werte im Kontext anzuwenden. 
    -- Außerdem haben Sie `Currying` kennen gelernt. Ein praktisches Muster, das sich hieraus 
    -- ableiten lässt, ist das folgende: 
    -- 
    -- pure f <*> x1 <*> x2 <*> .. <*> xn 
    --   wobei f  :: t1 -> t2 -> .. -> tn -> t' 
    --         x1 :: Applicative m => m t1 
    --         x2 :: Applicative m => m t2 
    --         .
    --         .
    --         xn :: Applicative m => m tn 
    -- 
    -- 
    -- `pure` hebt die Funktion f in den Kontext m und `<*>` wendet f nach und nach auf alle ihre 
    -- im Kontext liegenden Argumente t1 bis tn an. Vor dem Hintergrund, dass jedes `Applicative` 
    -- auch ein `Functor` ist, lässt sich das Muster noch etwas verkürzen: 
    -- 
    -- pure f <*> x1 <*> x2 <*> ... <*> xn 
    --      f <$> x1 <*> x2 <*> ... <*> xn 
    -- 
    -- 
    -- Importiert aus dem Modul AdressSys sind die folgenden Datentypen und Funktionen, die ein 
    -- ein Datenbanksystem zur Verwaltung persönlicher Daten repräsentieren: 
    -- 
    -- type ID = Integer
    -- type DB = [(ID,[Datum])]
    -- 
    -- newtype Age      = Age      Integer
    -- newtype Name     = Name     String
    -- newtype City     = City     String
    -- newtype Email    = Email    String
    -- newtype Phone    = Phone    String
    -- newtype Street   = Street   String
    -- newtype Gender   = Gender   String
    -- newtype Postcode = Postcode String
    -- 
    -- data Adress = Adress Name Street PostCode City deriving (Show,Eq)
    -- data Public = Public Name (Maybe Age) (Maybe Email) deriving (Show,Eq)
    -- 
    -- data Datum  = DName     Name
    --             | DStreet   Street
    --             | DPostcode Postcode
    --             | DEmail    Email
    --             | DPhone    Phone
    --             | DGender   Gender
    --             | DCity     City
    --             | DAge      Age
    --             deriving (Show,Eq)
    -- 
    -- getName     :: [Datum] -> Maybe Name 
    -- getStreet   :: [Datum] -> Maybe Street
    -- getPostcode :: [Datum] -> Maybe Postcode
    -- getEmail    :: [Datum] -> Maybe Email
    -- getPhone    :: [Datum] -> Maybe Phone
    -- getGender   :: [Datum] -> Maybe Gender
    -- getAge      :: [Datum] -> Maybe Age
    -- getCity     :: [Datum] -> Maybe City
    -- -- suchen jeweils das erste Vorkommen aus; gehen Sie davon aus, die Datenstruktur erlaube nur einmaliges Vorkommen
    -- 
    -- getDataFromID :: ID -> DB -> Maybe [Datum]
    -- -- sucht die zu einer ID zugehörigen Daten aus einer Datenbank aus 
    
    db1 = [(1,[DAge (Age 99),DCity (City "Portland,Oregano"),DName (Name "Mona D."),DPostcode (Postcode "42317"),DStreet (Street "Intuition 6")]),(2,[DStreet (Street "Jahnplatz 5"),DName (Name "Alfred Plickateff"),DAge (Age 22),DEmail (Email "a.plickateff@hackage.com")]),(3,[DName (Name "Gerhard Zeh")]),(4,[])]
    db2 = [(2,[DAge (Age 54),DCity (City "Bielefeld"),DName (Name "Hans Joachim Meyer"),DPostcode (Postcode "33602"),DStreet (Street "Viktoriastraße 22")]),(6,[DStreet (Street "Dönerteller 1a"),DName (Name "Hannelore Hacker"),DAge (Age 76)]),(3,[DName (Name "Lisa Lista"),DEmail (Email "lisa.lista@web.de"),DAge (Age 7)]),(5,[DName (Name "Alonzo Storch"),DStreet (Street "Antenne 2"),DCity (City "Dingenskirchen"),DPostcode (Postcode "12346")])]
    -- zwei Beispieldatenbanken
    
    -- Gegeben eine Liste von persönlichen Daten fassen die folgenden Funktionen `getAdressM` und 
    -- `getPublicDataM` Adress- bzw. öffentliche Daten zu einem entsprechenden Wert `Adress` bzw. 
    -- `Public` zusammen; falls nicht alle nötigen Informationen gefunden werden, geben sie `Nothing` 
    -- zurück. 
    
    getAdressM :: [Datum] -> Maybe Adress  
    getAdressM ds = do   
      name   <- getName     ds  
      street <- getStreet   ds  
      pcode  <- getPostcode ds  
      city   <- getCity     ds    
      return (Adress name street pcode city)  
    
    getPublicM :: [Datum] -> Maybe Public  
    
    getPublicM ds = getName ds >>= \name -> return (Public name (getAge ds) (getEmail ds))
    
    Nicole Dresselhaus's avatar
    Nicole Dresselhaus committed
    
    
    -- Implementieren Sie nun zwei Funktionen `getAdressA` und `getPublicDataA`, die das gleiche tun, 
    -- im Applicative style, d.h. indem Sie das oben beschriebene Muster verwenden. 
    
    getAdressA :: [Datum] -> Maybe Adress  
    getAdressA ds = undefined
    
    getPublicA :: [Datum] -> Maybe Public  
    getPublicA ds = undefined
    
    
    -- Definieren Sie abschließend eine Funktion `getManyAdresses` im Applicative style, die unter 
    -- Verwendung von `getAdressFromID :: ID -> DB -> Maybe Adress` Adressen für eine ganze Liste 
    -- von `ID`s aus einer Liste von Datenbanken `DB`s aussucht und ausgibt.  
    
    getAdressFromID :: ID -> DB -> Maybe Adress
    getAdressFromID iD db = getDataFromID iD db >>= getAdressM
    
    getManyAdresses :: [ID] -> [DB] -> [Maybe Adress]  
    getManyAdresses iDs dbs = undefined
    
    
    result = unlines $
              ["Adressen für Nutzer 1 bis 5 (ID) aus db1 und db2: ",  
              (show $ getManyAdresses [1..5] [db1,db2]),  
              "Öffentliche Daten für ID 1 db1: ",  
              (show $ (getDataFromID 1 db1 >>= getPublicA))]