How to print integer literals in binary or hex in haskell?

前端 未结 8 1320
说谎
说谎 2021-01-30 02:13

How to print integer literals in binary or hex in haskell?

printBinary 5 => \"0101\"

printHex 5 => \"05\"

Which libraries/functions allo

8条回答
  •  长发绾君心
    2021-01-30 02:57

    You could define your own recursive functions like:

    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
    

    Explanation: As you can see, the toNum function converts a k-based value to decimal, using the given base and a mapping function. The mapping function will map special characters to a decimal value (for ex. A=10, B=11, ... in hex). For binary mapping you could also use a lambda expression like you see in binToDec.

    Whereas the toKBaseVal function is the opposite, converting a decimal to a k-based value. Again we need a mapping function which does the opposite: from a decimal to the corresponding special character of the k-based value.

    As a test you can type:

    binToDec(decToBin 7) = 7
    

    Suppose you want to convert from decimal to octal:

    -- decimal to octal
    decToOct :: Int -> String
    decToOct x = toKBaseNum x 8 (\x -> intToDigit(x))
    

    Again, I use just a lambda expression, because the mapping is simple: just int to digit.

    Hope that helps! Good programming!

提交回复
热议问题