2009-12-28 7 views
8

Ich lerne Haskell. Ich habe eine Funktion erstellt, die die Multiplikationstabelle auf 'n' in der Basis 'b' zurückgibt. Zahlen werden auf "w" Ziffern aufgefüllt. Als letzten Schritt möchte ich 'w' automatisch berechnen. Warum kompiliert das nicht?Keine Instanz für (Floating Int)

-- Number of digits needed for the multiplication table n*n in base 'base' 
nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor (logBase base (n*n)) 

Fehler:

No instance for (Floating Int) 
    arising from a use of `logBase' at C:\haskel\dgnum.hs:4:24-38 
    Possible fix: add an instance declaration for (Floating Int) 
    In the first argument of `floor', namely `(logBase b (n * n))' 
    In the second argument of `(+)', namely `floor (logBase b (n * n))' 
    In the expression: 1 + floor (logBase b (n * n)) 

Antwort

10

LogBase hat zwei Parameter, die die Floating-typeclass implementieren. Sie müssen von Integral die Parameter aufrufen, bevor Sie sie an logBase übergeben. Das ist für mich zusammengestellt mit 6.10.3:

nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor (logBase (fromIntegral base) (fromIntegral (n*n))) 

Sie müssen bedenken, dass Haskell ist sehr stark typisiert, so kann man nicht einfach davon ausgehen, dass die Int-Parameter an die Funktion geliefert wird automatisch auf den schwimmenden Zahlen umgewandelt werden Diese Log-Funktionen nehmen in der Regel an.

5

logBase ist für die Arbeit mit Fließkommatypen deklariert. Int ist kein Fließkommatyp und es gibt no automatic conversion in Haskell. Versuchen Sie folgendes:

-- Number of digits needed for the multiplication table n*n in base 'base' 
nOfDg :: Int -> Float -> Int 
nOfDg n base = 1 + floor (logBase base (fromIntegral (n*n))) 
+0

Ich denke, Sie brauchen '(von Integral Basis)' auch. –

+0

@Jason: Nicht mit dem Typ Dan gab diese Funktion, werden Sie nicht. – Chuck

+0

Ja, hängt davon ab, wie Sie es verwenden möchten. Entweder tue ich es, wenn es in Ordnung ist, die Typ-Signatur zu ändern, oder verwende Andys Version, wenn nicht. –

3

Aus dem Vorwort:

logBase :: Floating a => a -> a -> a 

Es bedeutet, dass LogBase verwenden müssen Sie einen schwimmenden werden. Aber Int ist kein Schwimm Typ, und es gibt keine automatische Konvertierung für numerische Typen, so dass Sie es von Int Schwimmender konvertieren:

nOfDg n base = 1 + floor (logBase (toEnum base) (toEnum n)) 

die toEnum Funktion einen int als Parameter übernehmen und zurück ein " Enum "Typ. Das Gute ist, dass Float eine Instanz von Enum ist, so könnte man es Sie sollten

toEnum :: Enum a => Int -> a 

verwenden lesen/dokumentieren Sie Standardtypklassen in Haskell für numerische Typen (Num, Fractional, Integral, schwimmend ...) Da sie häufig im Code auftauchen, könnte das Lernen von Conversions nützlich sein.

Edit: diese Haskell Wiki Book bieten eine sehr nützliche Grafik der Beziehung zwischen Standards Typ Klasse, einschließlich numerischer Typen.

Verwandte Themen