2010-02-20 16 views
5

Ich habe eine Haskell-Funktion, die die Größe der Liste der endlichen Ints berechnet. Ich brauche den Ausgabetyp eine Integer zu sein, weil der Wert tatsächlich größer sein wird als die maximal Int gebunden (das Ergebnis wird -1 sein um genau zu sein, wenn der Ausgabetyp ein Int)Haskell Error: Der erwartete Typ `Integer 'konnte nicht mit dem abgeleiteten Typ' Int 'verglichen werden.

size :: a -> Integer 
size a = (maxBound::Int) - (minBound::Int) 

ich das verstehen Unterschied zwischen Ints (beschränkt) und Integers (unbegrenzt), aber ich möchte eine Integer aus einem Int machen. Ich habe mich gefragt, ob es eine Funktion wie fromInteger gibt, mit der ich einen Int-Typ in einen Integer-Typ umwandeln kann.

+0

Sie haben 'a' nicht verwendet. – kennytm

+0

(in re. @dons letzte Frage :) Von "Größe der Liste der endlichen Intents" meinst du, die Anzahl Elemente, die in einer Liste mit allen möglichen Ints wäre? – MtnViewMark

+0

@KennyTM, Ja, ich weiß :) Die Size-Funktion ist eine Eigenschaft einer Type-Klasse Finite, die für separate SubTypes (Int, Endprodukt usw.) überladen ist, so dass 'a' verwendet wird, um die zu verwendende Überlast – Fry

Antwort

11

Hier finden Sie die Werte zu ganzen Zahlen konvertieren müssen, die durch die fromIntegral Funktion (numerisch Casting für Haskell) getan werden kann:

fromIntegral :: (Integral a, Num b) => a -> b 

Es jede Art auf jede Art in der Integral-Klasse wandelt in der (größer) Num Klasse. Z.B.

Allerdings würde ich nicht wirklich den Ansatz vertrauen, den Sie nehmen - es scheint sehr fragil. Das Verhalten bei Typen, die einen Wraparound zulassen, ist ziemlich verdächtig.

Was meinst du wirklich mit: "die Größe der Liste der endlichen Intents". Was ist die Größe in diesem Sinne, wenn es nicht die Länge der Liste ist?

+0

Ja es ist im Wesentlichen die Länge der Liste, aber auch eine endliche Liste kann groß sein. Um die Länge einer Liste zu erhalten, müsste ich zuerst die Liste konstruieren und dann darüber interagieren. Auf diese Weise kann ich nur die Antwort erzeugen, ohne die ganze Liste zu erzeugen :) – Fry

4

ich Sie glauben suchen:

fromIntegral :: (Integral a, Num b) => a -> b 

, die wird eine Integer in eine Int konvertieren

+0

... und umgekehrt. (dh einen Int in einen Integer umwandeln) – BMeph

0

Vielleicht waren Sie davon aus, dass Haskell, wie viele Hauptstrom Sprachen wie C und (bis zu einem gewissen Extent) Java, hat implizite numerische Nullen. Es tut nicht: Int und Integer sind völlig nicht verwandte Typen und es gibt eine spezielle Funktion für die Konvertierung zwischen ihnen: fromIntegral. Es gehört zur Num-Klasse. Sehen Sie sich die Dokumentation an: Im Wesentlichen, von Integral, macht mehr als das: Es ist ein generisches "konstruiere die Darstellung einer beliebigen ganzen Zahl", t.i. Wenn Sie eine Art von Zahlen implementieren und Num instanziieren, müssen Sie eine Möglichkeit bereitstellen, ganzzahlige Zahlen Ihres Typs zu konstruieren. In der Num-Instanz für komplexe Zahlen erzeugt Integral beispielsweise eine komplexe Zahl mit einem Imaginärteil von Null und einem ganzzahligen Realteil. Der einzige Sinn, in dem Haskell implizite numerische Nullen hat, ist, dass Integer-Literale überladen sind, und wenn Sie 42 schreiben, interpretiert der Compiler implizit es als "fromIntegral (42 :: Integer)", so dass Sie Integer verwenden können Kontexte, in denen ein Num-Typ erforderlich ist.

+0

Sorry, ein Nitpicker zu sein (aber da es einen meiner Peeves über die Num-Klasse "stack" berührt, werde ich mich verwöhnen ...) aber seit dem 'Complex a' (was? keine Klasse? Ist das eine dieser "vorschnellen Optimierungen?) hat einen "RealFloat a" -Kontext, Ihre fromIntegral'd Complex-Nummer wird keinen integralen Realteil haben, sondern einen "Real", höchstwahrscheinlich einen Double. Anders als das kleine Quibble, das ist eine ziemlich gute Antwort - mach weiter! – BMeph

Verwandte Themen