Haskell Opdrachten Taal, Wiskunde, Logica

Tweede week

  1. Schrijf een functie die de lengte van een lijst uitrekent. De type-specificatie is:
    len :: [a] -> Int
    
  2. Schrijf een functie om het aantal voorkomens van een object in een lijst van objecten te tellen. De type-specificatie is:
     
    cnt :: Eq a => a -> [a] -> Int
    
    De specificatie betekent dat cnt werkt voor alle lijsten van objecten [a] die voldoen aan de eis van voor a de gelijkheidsrelatie == is gedefinieerd.

    Voorbeeld van een aanroep: cnt 'a' "Jan van Eijck"'. Dit moet 2 opleveren.

  3. Schrijf een functie om het aantal klinkers in een string te tellen. De type-specificatie is:
     
    vowelCnt:: String -> Int
    
    Probeer gebruik te maken van de functie cnt uit de vorige opdracht.
  4. We willen tekenrijtjes gaan analyseren, om na te gaan hoe vaak bepaalde letters erin voorkomen. Daarvoor is het gemakkelijk als we kunnen aannemen dat zo'n rijtje alleen kleine letters bevat (en dus geen hoofdletters). De functie
     
    toLower :: Char -> Char
    
    zet hoofdletters om in kleine letters, en laat de kleine letters ongemoeid. Deze functie is onderdeel van de Haskell module Char. Die kun je laden in Hugs met behulp van :l Char, of bovenaan je Haskell bestand aanroepen met import Char. Je ziet dan aan de prompt dat de module beschikbaar is.

    Gebruik nu toLower om een functie te schrijven die een string omzet in een string zonder hoofdletters.

  5. Nu willen we van een tekstrijtje weten hoe vaak elke letter erin voorkomt. Voor het gemak nemen we aan dat het rijtje bestaat uit kleine letters. De functie uit de vorige opdracht heeft daar als het goed is voor gezorgd. De functie cntAll krijgt het volgende type:
     
    cntAll :: String -> [(Char,Int)]
    
    De letters die niet voorkomen kunnen uit de opsomming van de aantallen worden weggelaten. Een aanroep gaat als volgt:
     
    Main> cntAll "Jan van Eijck"
    [('a',2),('c',1),('e',1),('i',1),('j',2),('k',1),('n',2),('v',1)]
    
  6. Als we nu ook nog het totale aantal lettertekens weten (alle lettertekens behalve de leestekens) kunnen we de frequentie van de afzonderlijke letters in de tekenreeks uitrekenen. Om letters te onderscheiden van niet-letters (bij voorbeeld leestekens of cijfers) kun je gebruik maken van de functie isAlpha, in de module Char.

    De type-declaratie voor de functie die we willen implementeren is:

     
    freqChar :: Char -> String -> Float
    
    Hierbij is Float het type van getallen met een drijvende comma (Engels: floating point numbers). Om het Float type te krijgen, moet je het Int type eerst omzetten. Dat kan met behulp van de ingebouwde functie fromIntegral. Als n en m van type Int zijn, dan is de uitdrukking fromIntegral n / fromIntegral m van type Float. Deze uitdrukking geeft de waarde van de breuk n/m.

    Een voorbeeld-aanroep van de functie:

     
    Main> freqChar 'a' "Jan van Eijck"
    0.1538462
    
    Nog een voorbeeld: freqChar 'a' "aaabbb" levert 0.5 op.
  7. Schrijf nu een functie die de frequenties uitrekent voor alle letters die in de reeks voorkomen, ten opzichte van het totaal van alle echte lettertekens in de reeks. De type-declaratie moet als volgt luiden:
    cntFreqs :: String -> [(Char, Float)]
    
    Hier zijn een paar voorbeelden van aanroepen:
    Main> cntFreqs "aabbbcccc"
    [('a',0.2222222),('b',0.3333333),('c',0.4444444)]
    Main> cntFreqs "Jan van Eijck"
    [('a',0.1818182),('c',0.09090909),('e',0.09090909),('i',0.09090909),('j',0.1818182),('k',0.09090909),('n',0.1818182),('v',0.09090909)]
    

    NB: vanaf hier zijn de vragen bonusvragen, bedoeld voor wie wil uitblinken.

  8. Prefixen of beginrijtjes van een lijst ys worden gedefinieerd door: De type-declaratie is:
    prefix :: Eq a => [a] -> [a] -> Bool
    
    De aanroep prefix "Ja" "Jan" moet True opleveren.
  9. Suffixen van een lijst zijn de eindrijtjes van die lijst. De definitie is analoog aan die van prefixen.

    Schrijf een functie suffixes die de lijst geeft van alle suffixen van een lijst. De type-declaratie:

    suffixes :: [a] -> [[a]]
    
    De functie levert dus een lijst van lijsten op (de lijst van alle suffixen). De aanroep suffixes "Jan" moet opleveren: ["Jan","an","n",""]. De opsomming van suffixen mag eventueel ook in een andere volgorde.
  10. We hebben gezien dat de belangrijke verschillen tussen lijsten en verzamelingen zijn: Stel nu dat we lijsten willen gebruiken om verzamelingen te representeren. Dan moeten we rekening houden met het feit dat [2,1,1], [2,1] en [1,2] als lijsten weliswaar allemaal verschillend zijn, maar dat ze allemaal dezelfde verzameling representeren.

    Schrijf een functie die van twee eindige lijsten nagaat of ze dezelfde verzameling representeren. Het type is:

     
    sameSet :: Eq a => [a] -> [a] -> Bool
    
    Je kunt, als je dat wilt, gebruik maken van de voorgedefineerde functies elem en and.

Huiswerk

Tekstbestand met alle antwoorden. Let op: de laatste drie vragen zijn bonusvragen. Deadline: dinsdag 13 mei, 12 uur 's middags. Per email inleveren bij Arno Bastenhof, met een cc naar Jan van Eijck.


Jan van Eijck
Last modified: Thu Apr 24 16:30:27 CEST 2008