Anfänger-Frage



  • Hallo,

    ich belese mich gerade etwas zu Haskell und dabei ist mir eine Frage zu den Typ-Klassen aufgekommen, die ich mir versucht habe zu erklären. Allerdings scheiter ich. Folgendes :

    iDontWork :: (Num a, Ord a) => a -> Bool
    iDontWork a = a <= 100.0
    

    Dieses Code-Stück compelliert nicht, da es anscheinend verlangt, dass ich zur Funktions-Definition Fractional a hinzufüge. Ich verstehe aber nicht, wieso. Floats und Doubles sind doch auch in Num, oder nicht? Sowas zB compiliert aber

    iDoWork :: (Num a, Ord a) => a -> a -> Bool
    iDoWork a b = a <= b
    

    und funktioniert auch für

    iDoWork 3 100.5
    

    . Ich verstehe den Unterschied irgendwie nicht. Das eine mal fühlt sich Haskell wohl dazu in der Lage, einen integralen Typ in float/double zu ändern und das andere Mal nicht?
    In dem Fall, wo 100.5 eine Konstante war, hat es nicht funktioniert, aber in dem Fall wo anstatt dieser 100.5 eine Variable steht, die später bei Funktionsaufruf aber auch den Wert 100.5 annimmt, nicht mehr?

    Bitte um Erklärung :p Danke schon mal im Voraus 🙂



  • Die Funktion ist zu speziell. Die Signatur erlaubt für a beliebige Nums, also z.B. auch Integer, aber mit Integer funktioniert der Vergleich nicht. Bei der zweiten funktioniert der Aufruf, weil für 3 und 100.5 -- aufgrund der Signatur -- derselbe Typ hergeleitet wird (ich nehme an Double).

    Disclaimer: Das ist mehr oder weniger ein educated guess, ich habs weder ausprobiert noch nachgeschlagen.



  • interessanter Fall.
    Vielleicht hilft das hier weiter:

    http://en.wikibooks.org/wiki/Haskell/Type_basics_II

    Wenn ich das richtig verstanden habe, musst du beim ersten Beispiel mit der Konstanten 100.0 Fractional verwenden weil:

    Prelude> :t 100.0
    100.0 :: Fractional a => a
    

    Da also 100.0 vom Typ Fractional ist und bei Vergleichoperatoren beide Seiten den gleichen Typ haben müssen, muss die Funktion das so wiederspiegeln.

    iDontWork :: (Fractional a, Ord a) => a -> Bool
    iDontWork a = a <= 100.0
    

    während beim zweiten Fall beide Parameter entsprechend konvertiert werden, um den Vergleich machen zu können.
    (Vermutung, bin auch noch absoluter Neuling)



  • Quisslich schrieb:

    während beim zweiten Fall beide Parameter entsprechend konvertiert werden, um den Vergleich machen zu können.
    (Vermutung, bin auch noch absoluter Neuling)

    In Haskell gibt es keine implizite Typumwandlung.



  • ähhh, ok, richtiger wäre dann zu sagen:

    ... damit die entsprechende Version der (<=)-Funktion gewählt werden kann ?



  • Kommt auf den vollständigen Satz an.



  • Ich habe mal gehört, dass gewisse Überklassen recht performancefressend sein sollen. Dieses und ihre Anfängerfeindliche (oder irreführende) Anwendung wie auch die interne Beschleunigung von Double könnte zu folgender Empfehlung reichen:
    Vorzugsweise Double verwenden 😉


Anmelden zum Antworten