Haskell



  • freakC++ schrieb:

    Ich vermute mal, Tim und ipsec haben recht.

    Sarkasmusdetektor vergessen?



  • freakC++ schrieb:

    Bis jetzt habe ich nicht komplett Neues erlebt und komme mit den Übungsaufgaben prima zurecht.

    Hast du den Thread bevor oder nachdem du mit Haskell angefangen hast eröffnet?



  • Ich kann mit gut vorstellen, dass er seinen zweite Sitzung hinter sich hat.



  • Wie gesagt: Das ist ja nur eine Vermutung! Es kann sein, dass ich mich irre.

    Ich bin tatsächlich in Haskell noch nicht weit und in C++ bin ich auch kein Profi. Bedeutet dies, dass man die Vorteile von Haskell erst in größeren Projekten merkt?

    Vielen Dank
    lg, freakC++



  • Eine gute Sache hat Haskell: Der Typ "Integer" ist nicht (abgesehen von der Größe des Arbeitsspeihers) begrenzt.



  • Eine gute Sache hat Haskell: Der Typ "Integer" ist nicht (abgesehen von der Größe des Arbeitsspeihers) begrenzt.

    🙄

    Ich glaube dein Problem ist eher die funktionale Programmierung an sich und nicht Haskell. Deswegen mal zum Lesen und Nachdenken:
    Why Functional Programming Matters
    Und für Haskell speziell:
    Why Haskell Matters



  • freakC++ schrieb:

    Irgendwer schrieb:

    Bei einer rein funktionalen Sprache muss man aber komplett (!) umdenken.

    Warum? Funktionen sehen ein bisschen komisch aus. Typen muss man wie in C++ unterscheiden. Es gibt halt keine Schleifen, aber das kann man rekursiv lösen. Bis jetzt habe ich nicht komplett Neues erlebt und komme mit den Übungsaufgaben prima zurecht.

    Geht mir genauso. Ich bin auch noch halbwegs am Anfang und komme von C++, kann aber von einem "kompletten Umdenken" nix entdecken. Zu viel Wind um die Sache oder kommt das einfach später?



  • Zeus schrieb:

    Schon mal nebenläufige- oder parallele Systeme/Anwendung programmiert?

    Ja, da braucht man kein Haskell und seine komische Denke.



  • PS: Und Haskell macht es einem auch nicht einfacher. Könnt ihr euch sparen, mir einreden zu wollen, dass da alles automatisch geht.



  • Wer zwingt euch eigentlich, Haskell zu lernen?



  • Mich keiner. Den freakC++ wahrscheinlich sein Lehrer/Prof.



  • freakC++ schrieb:

    Wie gesagt: Das ist ja nur eine Vermutung! Es kann sein, dass ich mich irre.

    spätestens, wenn du das lustige mapen und transformieren von unendlich langen Listen beginnst wirst du merken, dass da schon deutlich mehr hinter steckt.

    Ein Bekannter von mir programmiert seine eigenen Projekte immer in Haskell, ab und zu muss er aber irgendwas auf C/C++ portieren und kommt dann immer zu mir heulen wie häßlich C++ doch ist und dass in der Sprache simple Haskell 1-Zeiler dann bildschirmfüllende Funktionen sind...

    Haskell ist schon krass elegant.



  • otze schrieb:

    Ein Bekannter von mir programmiert seine eigenen Projekte immer in Haskell, ab und zu muss er aber irgendwas auf C/C++ portieren und kommt dann immer zu mir heulen wie häßlich C++ doch ist und dass in der Sprache simple Haskell 1-Zeiler dann bildschirmfüllende Funktionen sind...

    Was machen die Programme?
    Hast du mal ein Beispiel für so einen Einzeiler?



  • otze schrieb:

    Haskell ist schon krass elegant.

    Eleganz = Einfachheit x Allgemeinheit.

    Eine Programmiersprache, die I/O nur mit raffinierten Tricks aus der Kategorientheorie hinkriegt und mithilfe von Donuts veranschaulicht, ist nicht einfach, sondern unpraktikabel.



  • sagmal schrieb:

    Was machen die Programme?
    Hast du mal ein Beispiel für so einen Einzeiler?

    Das ist ne Menge Numbercrunshing stuff. Häufig irgendwelche sampling algorithmen für Wahrscheinlichkeitsverteilung. Einen solchen Einzeiler habe ich gerade nicht in der Hand, aber sowas hat er mir letztens geschickt:

    normalize w = map (/ (sum w)) w
    resampleweights particles oldP newP = normalize $ zipWith (/) (map newP particles) (map oldP particles)
    

    In C++ wäre das sowas wie:

    void normalize(Vector& w){
        double norm = std::sum(w.begin(),w.end());
        w/=norm;//angenommen wir habend en operator definiert...
    }
    Vector resampleWeights(const Vector& particles,Distribution oldP, Distribution newP){
        Vector weights(particles.size());
        for(size_t i = 0; i!= particles.size(); ++ i);
        {
            double weights[i] = oldP(particles[i])/newP(particles[i]);
        }
        normalize(weights);
        return weights;
    }
    

    @!rr!rr_.
    Ja, da muss man sich rein denken. trotzdem funktioniert es sehr gut, wenn man die Theorie verstanden hat, und so schwer ist es nicht. Man muss sich das nur so vorstellen, als wenn jede Funktion einen impliziten Parameter für den aktuellen Zustand hat und als Rückgabewert zusätzlich den aktuellen Zustand mit raus gibt. Das es so mathematisch ausgedrückt wird, liegt an der mathematischen Denkweise der Haskell programmierer.



  • Das ganze könnte man schon kürzer machen (ungetestet)

    void normalize(Vector &v) {
      Vector::value_type const sum = std::accumulate(v.begin(), v.end(), Vector::value_type());
      std::transform(v.begin(), v.end(), [sum](Vector::value_type i) { return v / sum });
    }
    
    Vector resampleWeights(Vector particles, Distribution oldP, Distribution newP){
      std::transform(particles.begin(), particles.end(), particles.begin(), [](Vector::value_type i) { return oldP(i)/newP(i); })
      normalize(particles);
      return particles;
    }
    


  • das ganze geht mit einer reinen OOP-Sprache a la Smalltalk auch in 2 Zeilen:

    weights := particles collect: [ :i | (oldP value: i) / (newP value: i) ].
    weightsNormed := weights collect: [ :x | x / weights sum ].
    

    - dafür brauche ich also kein Haskell.



  • Die Argumentation über kurze, knappe Formulierung ist einfach nicht zielführend.



  • sogar in 1 Zeile:

    weightsNormed := (particles collect: [ :i | (oldP value: i) / (newP value: i) ]) collect: [ :x | x / weights sum ].
    


  • var weights = from i in particles select oldP(i) / newP(i);
    var sum = weights.Sum();
    var weightsNormed = from i in weights select weights / sum;
    

    Hätte man auch genauso wie die Smalltalk-Version schreiben können:

    var weights = particles.Select(i => oldP(i) / newP(i));
    var weightsNormed = weights.Select(i => i / weights.Sum());
    

    aber dann würde weights.Sum() für jedes Element neuberechnet werden. Ich vermute, das ist in Smalltalk nicht anders.

    Die Einzeiler-Lösung in Smalltalk ist offensichtlich Quatsch, von welchen weights soll denn da die Summe bestimmt werden?

    Insgesamt finde ich die Haskell-Lösung am elegantesten, wegen ihrer Modularität.


Anmelden zum Antworten