Vous pouvez définir vos propres fonctions récursives comme:
import Data.Char (digitToInt)
import Data.Char (intToDigit)
-- generic function from base to decimal
toNum :: [Char] -> Int -> (Char -> Int) -> Int
toNum [] base map = 0
toNum s base map = base * toNum (init(s)) base map + map(last(s))
-- generic function from decimal to base k
toKBaseNum :: Int -> Int -> (Int -> Char) -> [Char]
toKBaseNum x base map | x < base = [map x]
| otherwise = toKBaseNum (x `div` base) base map ++ [map(x `mod` base)]
-- mapping function for hex to decimal
mapHexToDec :: Char -> Int
mapHexToDec x | x == 'A' = 10
| x == 'B' = 11
| x == 'C' = 12
| x == 'D' = 13
| x == 'E' = 14
| x == 'F' = 15
| otherwise = digitToInt(x) :: Int
-- map decimal to hex
mapDecToHex :: Int -> Char
mapDecToHex x | x < 10 = intToDigit(x)
| x == 10 = 'A'
| x == 11 = 'B'
| x == 12 = 'C'
| x == 13 = 'D'
| x == 14 = 'E'
| x == 15 = 'F'
-- hex to decimal
hexToDec :: String -> Int
hexToDec [] = 0
hexToDec s = toNum s 16 mapHexToDec
-- binary to decimal
binToDec :: String -> Int
binToDec [] = 0
binToDec s = toNum s 2 (\x -> if x == '0' then 0 else 1)
-- decimal to binary
decToBin :: Int -> String
decToBin x = toKBaseNum x 2 (\x -> if x == 1 then '1' else '0')
-- decimal to hex
decToHex :: Int -> String
decToHex x = toKBaseNum x 16 mapDecToHex
Explication: Comme vous pouvez le voir, la fonction tonum convertit une valeur basée k à la décimale, en utilisant la base donnée et une fonction de mappage . La fonction de mappage mappera les caractères spéciaux à une valeur décimale (par exemple A = 10, B = 11, ... en hexadécimal). Pour le mappage binaire, vous pouvez également utiliser une expression lambda comme vous le voyez dans binToDec.
Considérant que la fonction toKBaseVal est l'inverse, en convertissant une décimale en une valeur basée sur k.Encore une fois nous avons besoin d'une fonction de mappage qui fait le contraire: d'une décimale au caractère spécial correspondant de la valeur basée sur k.
En tant que test, vous pouvez taper:
binToDec(decToBin 7) = 7
Supposons que vous voulez convertir des décimales en octal:
-- decimal to octal
decToOct :: Int -> String
decToOct x = toKBaseNum x 8 (\x -> intToDigit(x))
Encore une fois, je viens d'utiliser une expression lambda, parce que la cartographie est simple: Juste pour digit.
Espérons que ça aide! Bonne programmation!
Pour quelqu'un paresseux comme moi qui n'a pas fait défiler vers le bas, l'exemple printf est beaucoup plus concis et flexible, et peut faire d'autres choses utiles comme par ex. donne une chaîne de longueur constante et toutes les autres fonctions printf. Au lieu de ci-dessus, juste: 'printf"% 032b "5' – mozboz
@mozboz,' printf' dans Haskell est plus comme un tour de magie qu'une fonction à utiliser dans le code sérieux. La chaîne de format est analysée lors de l'exécution (ce qui peut générer des erreurs d'exécution) et l'ensemble du mécanisme est un peu lent. – dfeuer
Celui-ci ne fonctionne pas avec des nombres négatifs. – CMCDragonkai