Funktionen als Resultate - Lifting ...

  • Hi, 7.Teil Folie 22.


    Funktionen als Resultate - Anehgen eines Wertes zu einer (konstanten) Funktion ...


    constFun :: a -> (b -> a)
    constFun c = \x -> c


    Also ich interpretier das ganze so, constFun ist eine Funktion die ein Element eines belieben Typs auf eine einelemente Funktion abbildet (welche eine Abbildung von Typ b auf Typ a ist).


    ... ok soweit so klar ...


    weiters diese Funktion liefert immer c zurück, egal was übergeben wird.


    Hmm ... irgendwie erschließt sich mir der Sinn dahinter nicht. Auch die angegebenen Beispiele check ich nicht.


    Hat jemand vielleicht eine Erklärung dafür?


    Danke

  • Hi,


    ja, deine Interpretation stimmt. So etwas macht zum Beispiel Sinn, wenn du eine andere Funktion aufrufen möchtest, die eine Funktion als Argument bekommt. Wenn du zum Beispiel in einer Liste alle Elemente durch den String "abc" ersetzen willst, geht das ganz elegant durch:
    map (constFun "abc") liste


    Ok, das ist jetzt ein ziemlich konstruiertes Beispiel, aber das Prinzip sollte verständlich sein :-)
    Aja, außerdem wird bei Monaden als return- Funktion manchmal gern etwas Ähnliches verwendet, fällt mir gerade ein..




    mfg, Chris

    hi, i'm a signature virus. copy me into your signature to help me spread.

  • Ah, ok. Danke für die Antwort.


    Eigentlich könnt ich das ganze gleich so schreiben:
    constFun2 :: a -> (b -> a)
    constFun2 c = \_ -> c


    Weil x sowieso egal ist.


    Bzw. das Lambda Lifting immer anonym verwenden
    z.B.


    map (\_x -> 5) [1,2,3,4,5]


    Aber jetzt is es mir auf alle Fälle klar. Vielen Dank.


  • Ist das also eine Art "Kompatibilitäts work-around" wie curry?

  • OK. Jetzt verstehe ich.
    In Haskell wird sogenante anonyme Funktionen definiert, wenn der Name keine Rolle spielt. Die sind Lambda-artig Notation Varianten.

  • Könnte jemand mir erklären, warum diese Funktion anonym ist? Eigentlich ich verstehe nicht die ganze syntax!

    (\n -> (add 2) n)

    Danke.


    Naja, anonym deshalb weil du sie so nur einer anderen Funktion als Parameter übergeben kannst. Du hast keine Möglichkeit sie wieder explizit aufzurufen.


    Folgendes Beispiel könnte dir die Anwendung etwas klarer machen:


    Code
    1. add :: Int -> Int -> Int
    2. add = (+)
    3. myFun :: Int -> Int
    4. myFun x = (add 2) x


    jetzt hast du eine Liste von Zahlen die du alle um 2 erhöhen möchtest.
    Du könntest jetzt eine rekursive Funktion schreiben -->


    Code
    1. sillyFun :: [Int] -> [Int]
    2. sillyFun [] = []
    3. sillyFun (x:xs) = (myFun x):sillyFun xs
    4. sillyFun [1,2,3,4]


    oder du machst das ganze super cool elegant (etc... weiter superlative siehe folien :thumb:)


    und schreibst das ganze so:


    Code
    1. map (\n -> (add 2) n) [1,2,3,4]


    solche Lambda Definition können verwendet werden, wenn du eine Funktion nur einmal brauchst und es deshalb keinen Sinn machen würde sie mitzuübergeben.


    Kennst du vielleicht in Java das Konzept für Anonyme Klassen in einer Methode. Da ist es so ähnlich.


    Code
    1. button.addActionListener(
    2. new ActionListener(){
    3. public void actionPerformed(Action e){
    4. // ....
    5. }
    6. }
    7. );


    Da wird eine Klasse erzeugt die direkt ein Interface implementiert, aber sonst nicht mehr instanziert werden kann.


    Ich hoffe ich konnte alle Klarheiten beseitigen ;)