2016-07-20 11 views
1

Ich versuche, eine Liste der Ziffern von einer Reihe zu bekommen, hier ist mein Code:Fehlertypen immer in Haskell passen

digits x = if x > 0 then (i : digits (floor (x/10))) else [i] 
    where i = (mod x 10) 

Der Fehler, den ich für diesen Code zu bekommen ist:

No instance for (Integral a0) arising from a use of ‘it’ 
    The type variable ‘a0’ is ambiguous 
    Note: there are several potential instances: 
     instance Integral Integer -- Defined in ‘GHC.Real’ 
     instance Integral Int -- Defined in ‘GHC.Real’ 
     instance Integral Word -- Defined in ‘GHC.Real’ 
    In the first argument of ‘print’, namely ‘it’ 
    In a stmt of an interactive GHCi command: print it 

was mache ich falsch?

+0

Verwenden Sie 'div' anstelle von'/'und' floor' – Carsten

+0

'' digits x = wenn x> 0 dann (x 'mod' 10): Ziffern (x' div' 10) else [x 'mod'10 ] '' - Bitte beachten Sie, dass Sie eine umgekehrte Liste (und eine unerwünschte "0" in den meisten Fällen) erhalten werden – Carsten

+1

Das ist eine GHCi-Fehlermeldung vom Versuch, _use_ die Funktion in einem Kontext zu verwenden. Fügen Sie Ihren Funktionen immer Typensignaturen hinzu, damit die Probleme sofort erkennbar werden und nicht woanders. – leftaroundabout

Antwort

2

auf Kommentar Carsten Zu erarbeiten, das Problem ist, dass Haskell die Art Signatur

digits :: (RealFrac a, Integral a) => a -> [a] 

wenn das, was Sie wollten, war

digits :: Integral a => a -> [a] 

Der Grund ist es das ehemalige folgert folgert, dass Sie verwenden (/) und floor, die in den Klassen Fractional und RealFrac definiert sind. Wie Linksaround um zeigt, ist dies nicht wirklich ein Problem, bis Sie versuchen, Ihre Funktion mit einer tatsächlichen Zahl auszuführen, zu welchem ​​Zeitpunkt Haskell keine gute Zahl Typ zu finden ist (Haskell Nummer Literale sind tatsächlich polymorph, und es gibt spezielle Standardregeln für, wenn Sie nicht explizit einen Typ deklarieren), daher die seltsame Fehlermeldung. Sie würden eine aussagekräftigeren Fehlermeldung erhalten, wenn Sie so etwas wie digits (1 :: Int) versucht:

<interactive>:19:1: error: 
    • No instance for (RealFrac Int) arising from a use of ‘digits’ 
    • In the expression: digits (1 :: Int) 
    In an equation for ‘it’: it = digits (1 :: Int) 

Das Update, wie Carsten wies darauf hin, ist div zu verwenden, statt (/) und floor.

+0

Vielen Dank für die gründliche Erklärung –

+1

gute Antwort - Ich denke, wir sollten wahrscheinlich so etwas im Haskell-Tag oder in der (Beta?) Dokumentation, an der StackExchange arbeitet, als diese Frage/Problem bearbeiten (mit '(/) 'where' div' wird benötigt) ist wirklich ein häufiges Problem hier - leider konnte ich keinen der anderen Vorkommen finden, um dies auch zu verbinden (wie normalerweise der Titel das Problem nicht direkt anzeigt) – Carsten

+0

@Carsten Wo würdest du empfehlen, es zu setzen da drin? Ich stocherte ein bisschen herum, aber ich konnte wirklich keinen Platz für so etwas finden ... – Alec