Ich spiele mit Anfänger Haskell herum und wollte eine durchschnittliche Funktion schreiben. Es schien das Einfachste auf der Welt zu sein, oder?
Falsch.
Es scheint, als ob das Typensystem von Haskell es dem Durchschnitt verbietet, an einem generischen numerischen Typ zu arbeiten - ich kann ihn dazu bringen, an einer Liste von Integralen oder einer Liste von Brüchen zu arbeiten, aber nicht an beiden.
Ich will:
average :: (Num a, Fractional b) => [a] -> b
average xs = ...
Aber ich kann nur bekommen:
averageInt :: (Integral a, Fractional b) => [a] -> b
averageInt xs = fromIntegral (sum xs) / fromIntegral (length xs)
oder
averageFrac :: (Fractional a) => [a] -> a
averageFrac xs = sum xs / fromIntegral (length xs)
und der zweite scheint zu funktionieren. Bis ich versuche, eine Variable zu übergeben.
*Main> averageFrac [1,2,3]
2.0
*Main> let x = [1,2,3]
*Main> :t x
x :: [Integer]
*Main> averageFrac x
<interactive>:1:0:
No instance for (Fractional Integer)
arising from a use of `averageFrac ' at <interactive>:1:0-8
Possible fix: add an instance declaration for (Fractional Integer)
In the expression: average x
In the definition of `it': it = averageFrac x
Anscheinend ist Haskell sehr wählerisch in Bezug auf seine Typen. Das macht Sinn. Aber nicht, wenn sie beide [Num] sein könnten
Vermisse ich eine offensichtliche Anwendung von RealFrac?
Gibt es eine Möglichkeit, Integrale in Brüche zu zwingen, die nicht ersticken, wenn sie eine Bruchteileingabe erhalten?
Gibt es eine Möglichkeit, eine polymorphe Durchschnittsfunktion zu verwenden Either
und either
zu erstellen, die für jede Art von numerischem Array funktioniert?
Verbietet das Typensystem von Haskell, dass diese Funktion jemals existiert?
Haskell zu lernen ist wie Kalkül zu lernen. Es ist wirklich kompliziert und basiert auf Bergen der Theorie, und manchmal ist das Problem so verblüffend komplex, dass ich nicht einmal genug weiß, um die Frage richtig zu formulieren, sodass jede Einsicht sehr akzeptiert wird.
(Auch Fußnote: Dies basiert auf einem Hausaufgabenproblem. Alle sind sich einig, dass durchschnittliches Frac oben volle Punkte erhält, aber ich habe den schleichenden Verdacht, dass es eine Möglichkeit gibt, es sowohl auf Integral- als auch auf Fractional-Arrays zum Laufen zu bringen.)