Anzeige

Haskell Funktion implementieren mit Strings

#1
Hallo,

das ist mein allererster Beitrag in diesem Forum:)

Die Aufgabe lautet:
Implementieren Sie eine Verarbeitung von Kommandozeilenparametern mittels pattern matching in Haskell! Folgende Switches müssen verarbeitet werden:
-r setzt result auf -3
-k setzt result auf 1
-i addiert 1 zu result
-h halbiert result (gemäß Integer-Division)
-t verdreifacht result
Fügen Sie Ihre Implementierung ans Ende von switch.hs an.

Ich habe folgenden Code gegeben:
Code:
import System.Environment

main = getArgs >>= print . (foldr apply 0) . reverse

apply :: String -> Integer -> Integer
Was ich bisher habe:
Also ich hab verstanden, dass apply als Parameter einen String und einen Integer bekommt und der Rückgabetyp ein Integer wieder ist. Weil wir in dem vorgegeben Code kein result gegeben haben, dachte ich, dass es hier das foldr (initialisiert mit 0) ist. Aus der main-Funktion werde ich aber nicht wirklich schlau. Hoffe ihr könnt sie mir erklären:)

Mein Code dazu (hoffe, dass ich da nicht völligen Mist produziert hab):
Code:
import System.Environment

main = getArgs >>= print . (foldr apply 0) . reverse

apply :: String -> Integer -> Integer
apply foldr | getArgs == -r -> -3 -> -3
            | getArgs == -k -> 1 -> 1
            | getArgs == -i -> foldr+1 -> foldr+1
            | getArgs == -h -> foldr/2 -> foldr/2
            | getArgs == -t -> foldr*3 -> foldr*3
            |otherwise = 0
 

ComFreek

Mod | @comfreek
Moderator
#2
Hallo PrologBegin!

main = getArgs >>= print . (foldr apply 0) . reverse
Ich würde mit dieser Zeile anfangen und versuchen zu verstehen, was genau >>= und "." in Haskell sind und tun. Insbesondere ist das "(foldr apply 0)" immer noch eine Funktion, die die Datenstruktur erwartet, über die gefolded werden soll. Siehe Fold im HaskellWiki: foldr bekommt immer Funktionen für alle Konstruktoren geliefert + die Datenstruktur an sich. Im Falle von Listen sind die Konstruktoren "cons: a -> List a -> List a" fürs Anhängen und "nil: List a". Beachte, dass Funktionen für Konstruktoren, die keine Argumente nehmen (hier "nil") einfach nur Werte sind.

Daraus und weil apply den Typ "String -> Integer -> Integer" hat, kann man schon schließen, dass die Liste, über die gefolded wird, eine Liste von Strings sein muss und das foldr auf dieser Liste insgesamt einen Integer produzieren wird.

Wenn ich mich recht entsinne, ist "." in Haskell der Funktionskompositionsoperator. Dann ergibt das sogar Sinn: "print . (foldr apply 0) . reverse" ist nichts anderes als "\x. print(foldr(apply)(0)(reverse(x))". Wenn jetzt "getArgs >>=" zufälligerweise noch genau die Argumente des Progammaufrufs als Liste von Strings übergibt, dann ist deine Main äquivalent zu "print(foldr(apply)(0)(reverse(getArgs)))".
Kannst du an dieser (gedanklichen) Form ablesen, was die Main tut?

*) \x. soll bei hier für Funktionsabstraktion stehen, also \x. x ist eine Funktion, die ein Argument bekommt und ebenjenes auch wieder zurückgibt. Das entspricht einem λ, falls du den Lambda-Kalkül kennst, oder ↦ in mathematischer Schreibweise (x ↦ 3x).
 
Anzeige
Anzeige