Frage

Ich lerne Haskell und steckte versuchen, das Typ-System zu verstehen.

Ich versuche, eine Funktion zu schreiben, die die Länge der Serie ‚Die Hälfte oder Drei-Plus-Eins‘ für eine Eingabe zurückgibt. Hier ist mein Versuch, die Funktion, einen rekursiven Ansatz (die Funktion ist gültig für Integral-Eingänge):

hotpo :: (Integral a) => a->a
hotpo n = hotpoHelper n 1

hotpoHelper:: (Integral a) => a->a->a
hotpoHelper 1 n = n
hotpoHelper num count
    | even num = hotpoHelper (truncate (num/2)) (count+1)
    | otherwise = hotpoHelper (3*num+1) (count+1)

Dies ist die Störung, die ich erhalte, wenn ich versuche in GHC 6.12.3 diese Datei zu laden

test.hs:8:30:
    Could not deduce (RealFrac a) from the context (Integral a)
      arising from a use of `truncate' at test.hs:8:30-45
    Possible fix:
      add (RealFrac a) to the context of
        the type signature for `hotpoHelper'
    In the first argument of `hotpoHelper', namely
        `(truncate (num / 2))'
    In the expression: hotpoHelper (truncate (num / 2)) (count + 1)
    In the definition of `hotpoHelper':
        hotpoHelper num count
                      | even num = hotpoHelper (truncate (num / 2)) (count + 1)
                      | otherwise = hotpoHelper (3 * num + 1) (count + 1)

take (truncate (5/2)) [1,2,3] funktioniert, so dass ich nicht in der Lage diese Fehlermeldung zu verstehen. Wo bin ich falsch gehen?

War es hilfreich?

Lösung

Der / Operator in Haskell ist für Floating-Point-Division verwendet. Wenn Sie wirklich Punktteilung und truncate wollten verwenden schwimmend, dann würden Sie fromIntegral auf num verwenden es zuerst zu einer Gleitkommazahl zu konvertieren. Der Fehler, den Sie erhalten, ist zu sagen, dass Sie nicht eine Bruchteilungs auf einer ganzen Zahl (5/2 funktioniert, weil der Compiler folgert eine Gleitkomma-Typ für beide Zahlen) verwenden können. Allerdings können Sie tun, was Sie viel mehr wollen einfach, die div Funktion. Dies wird normalerweise verwendet, Infix, durch rund um die Funktionsnamen mit einfachen Anführungszeichen (dies funktioniert für jede Haskell-Funktion):

| even num = hotpoHelper (num `div` 2) (count+1)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top