你可以定义你自己喜欢的递归函数:
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
说明: 正如你所看到的,toNum功能转换的k基于价值为十进制,使用给定的基础和映射函数。映射函数将特殊字符映射为十进制值(例如,A = 10,B = 11,...,十六进制)。对于二进制映射,您也可以使用像在binToDec中看到的lambda表达式。
而toKBaseVal函数是相反的,将小数转换为基于k的值。我们再次需要一个映射函数,它相反:从十进制到基于k值的对应特殊字符。
作为一个测试,你可以输入:
binToDec(decToBin 7) = 7
假设你想从十进制转换为八进制:
-- decimal to octal
decToOct :: Int -> String
decToOct x = toKBaseNum x 8 (\x -> intToDigit(x))
同样,我只使用一个lambda表达式,因为映射很简单:只需诠释数字。
希望有帮助!好的编程!
对于像我这样没有向下滚动的懒惰的人来说,printf示例更加简洁灵活,并且可以执行其他有用的操作,例如,给出一个恒定长度的字符串和所有其他printf功能。而不是以上,只是: 'printf“%032b”5' – mozboz 2015-06-24 11:36:08
@mozboz,Haskell中的'printf'更像是一个魔术,而不是一个用在严肃代码中的函数。格式字符串在运行时被解析(这可能会产生运行时错误),整个机制有点慢。 – dfeuer 2015-10-18 16:15:00
这一个不适用于负数。 – CMCDragonkai 2017-04-04 13:04:42