Se podría definir sus propias funciones recursivas como:
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
Explicación: Como se puede ver, el función toNum convierte un valor basado en k a decimal, utilizando la base dada y una función de mapeo . La función de mapeo mapeará caracteres especiales a un valor decimal (por ej. A = 10, B = 11, ... en hexadecimal). Para el mapeo binario también puedes usar una expresión lambda como la que ves en binToDec.
Considerando que la función toKBaseVal es lo contrario, convirtiendo un valor decimal en un valor k.Nuevamente, necesitamos una función de mapeo que haga lo contrario: de un decimal al carácter especial correspondiente del valor basado en k.
Como prueba puede escribir:
binToDec(decToBin 7) = 7
Supongamos que desea convertir de decimal a octal:
-- decimal to octal
decToOct :: Int -> String
decToOct x = toKBaseNum x 8 (\x -> intToDigit(x))
Una vez más, yo uso sólo una expresión lambda, porque la asignación es simple: solo int a digit.
Espero que ayude! Buena programación!
Para cualquier persona perezosa como yo que no se desplazó hacia abajo, el ejemplo de printf es mucho más conciso y flexible, y puede hacer otras cosas útiles, como p. Ej. dar una cadena de longitud constante y todas las demás características de printf. En lugar de arriba, solo: 'printf"% 032b "5' – mozboz
@mozboz,' printf' en Haskell es más como un truco de magia que una función para ser usado en código serio. La cadena de formato se analiza en tiempo de ejecución (lo que puede producir errores de tiempo de ejecución) y todo el mecanismo es un poco lento. – dfeuer
Éste no funciona con números negativos. – CMCDragonkai