2016-10-15 4 views
2

zu konvertieren Ich versuche, einen Code zu schreiben, um eine Ganzzahl zu nehmen und diese Ganzzahl in Worten auszugeben. Bsp .: Wenn die Eingabe 4321 ist, ist die Ausgabe viertausenddreihundertzehnundzwanzig. Dazu möchte ich zunächst die Eingabe in die einzelnen Ziffern zerlegen. Ex-Eingang 4321 würde eine Anordnung von [4,3,2,1] werden.Ich versuche, Ints in Zeichenfolgen in Haskell

Mein aktueller Code

newtype wordInt = WI Int 

instance Show WordInt where 
    show (WI x) | x>= 0 = helper x 
       | x < 0 = helper -x 

helper 0 = [0] 
helper x = x `mod` 10 : helper (x `div` 10) 

Im Moment denke ich, ich bin ein Typ Fehler. Bitte beachten Sie, dass dies in der Lage sein muss, sowohl positive als auch negative Zahlen zu übergeben. Wenn Sie sich einen effizienten Weg vorstellen können, um die gewünschte Konvertierung durchzuführen, wäre dies sehr zu begrüßen.

+0

Ihre Hilfsfunktion ist in Ordnung (bis zur Verwendung von '' 'anstelle von' \ '' auf 'div'), aber geht nur halbwegs zu Ihrem Ziel; h. es bricht die Eingabe in ihre einzelnen Ziffern auf, übersetzt sie jedoch nicht in Wörter. Deshalb beschwert sich der Compiler. –

+0

das war ein Tippfehler, als ich es zum Stack hinzugefügt habe. Mein tatsächlicher Code hat 'div' nicht 'div'. – Rick

+0

Und vergiss nicht das -minInt == minInt. – augustss

Antwort

2

Namen von Typen dürfen nicht mit einem Kleinbuchstaben beginnen. Ändern wordInt-WordInt hier:

newtype wordInt = WI Int 

Verfahren show der Show Klasse muss ein String und Ihre helper Rückkehr hat den Typen Int -> [Int] (wenn sie ein Int angewandt). Sie müssen irgendwie die Liste in eine String, zum Beispiel zu konvertieren, indem show auf der Liste aufrufen:

instance Show WordInt where 
    show (WI x) | x >= 0 = show $ helper x 
       | x < 0 = show $ helper (-x) 

Schließlich bemerken, dass ich -x in Klammern gesetzt. Dies wird für ein unäres Minus benötigt, da der Compiler andernfalls denkt, dass Sie versuchen, x von helper zu subtrahieren (was eine Funktion und keine Int ist).

Ihre Implementierung von helper ist jedoch falsch, da sie die Liste der Ziffern in umgekehrter Reihenfolge zurückgibt. Um dies zu beheben, können Sie eine Hilfsfunktion schreiben, um die Ziffern zu spalten und dann die Liste umkehren:

helper :: Int -> [Int] 
helper = reverse . go 
    where go 0 = [0] 
      go x = x `mod` 10 : go (x `div` 10) 

Dies wird jedoch Pad die Zahl mit einer führenden Null:

λ. helper 4321 
[0,4,3,2,1] 

Dies gilt nicht ändert die Bedeutung, natürlich, aber wenn es ein Problem ist, schreiben sie eine Wrapper-Funktion mit diesem Fall zu befassen:

helper :: Int -> [Int] 
helper x = 
    case splitIntoDigits x of 
     [] -> [0] 
     xs -> reverse xs 

splitIntoDigits :: Int -> [Int] 
splitIntoDigits 0 = [] 
splitIntoDigits x = x `mod` 10 : splitIntoDigits (x `div` 10) 

es dann in beiden Fällen funktioniert:

λ. helper 0 
[0] 
λ. helper 4321 
[4,3,2,1] 
+0

Ich habe gerade bemerkt, dass Ihre 'Helfer'-Implementierung auch falsch ist (im Sinne von falschen Antworten). Ich werde meine Antwort in Kürze aktualisieren. – dkasak

+0

Wäre es nicht besser, die Liste umgekehrt zu haben? Vorausschauend, wäre es nicht einfacher, in Text zu konvertieren, indem Sie die eine Ziffer vor der Zehnerstelle verarbeiten? – Rick

+0

Was meinst du mit "die Liste umgekehrt zu haben"? Wenn Sie vorhaben, es umgekehrt zu konstruieren, ist dies möglich (indem Sie '(++)' zum Anhängen verwenden), aber ineffizient, wenn Sie die Zahl vom kleineren zum größeren Ende (von rechts nach links) verarbeiten. In Bezug auf Ihre zweite Frage verarbeiten Sie bereits die Ziffern vor der Zehnerstelle.Hast du vor, die Zahl von links nach rechts zu verarbeiten? – dkasak

Verwandte Themen