简体   繁体   English

Haskell 返回十六进制值列表

[英]Haskell returning list with hexadecimal value

I am trying to define the function "decToHex" which returns a list of chars that corresponds to the hexadecimal value of a given number.我正在尝试定义 function “decToHex”,它返回与给定数字的十六进制值相对应的字符列表。 For example, 1128 = ['4','6','8']例如,1128 = ['4','6','8']

This is my function这是我的 function

decToHex :: Int -> [Char]
list = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]
listHexa = []
decToHex x
  | x < 16 = list !! x
  | otherwise = decToHex (x `div` 16) : ((list !! (x `mod` 16)) : listHexa)

But I get this error:但我得到这个错误:

• Couldn't match type ‘[Char]’ with ‘Char’
  Expected type: [Char]
    Actual type: [[Char]]
• In the expression:
    decToHex (x `div` 16) : ((list !! (x `mod` 16)) : listHexa)

What am I missing?我错过了什么?

Your list is of type [String] , because every letter there is a String .您的list[String]类型,因为每个字母都有一个String Instead, make it a list of Char by replacing double quotes with single ones.相反,通过用单引号替换双引号使其成为Char列表。

Recall asymmetric operator : adds an element to the left of a list, while symmetric operator ++ concatenates two lists.回想一下不对称运算符:在列表的左侧添加一个元素,而对称运算符++连接两个列表。

Hence, for an expression that starts with:因此,对于以以下方式开头的表达式:

decToHex (x `div` 16) :  ... whatever ...

the left operand of : is already a string, that is a list of Char's. :的左操作数已经是一个字符串,即一个 Char 的列表。 So the type of the whole expression has to be [[Char]] .所以整个表达式的类型必须是[[Char]] But this conflicts with your type signature for function decToHex , which says it returns just a [Char] simple list.但这与您的 function decToHex类型签名相冲突,后者表示它只返回一个[Char]简单列表。

Side note 1: things are less confusing when the list of hexadecimal digits is called hexDigits rather than plain list .旁注 1:当十六进制数字列表被称为hexDigits而不是普通的list时,事情就不会那么混乱了。

Side note 2: in a division, if you need both the quotient and the remainder, it is more readable and more efficient to use function divMod rather than div and mod separately.旁注2:在除法中,如果您需要商和余数,则使用 function divMod而不是单独使用divmod更具可读性和效率。

We thus have the following code:因此,我们有以下代码:

hexDigits  = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]

decToHex :: Int -> [Char]
decToHex x
    | x < 0      =  '-' : decToHex (-x)
    | x < 16     =  hexDigits !! x
    | otherwise  =  let  (q, r) = divMod x 16
                    in  (decToHex q)  ++  (hexDigits !! r)

Side note 3:旁注3:

Just like everything else, lists are immutable in Haskell.就像其他一切一样,列表在 Haskell 中是不可变的。 This implies that operator ++ has to work by duplicating its left operand .这意味着运算符++必须通过复制其左操作数来工作。 Hence, using ++ for recursion in such a way is very inefficient.因此,以这种方式使用++进行递归是非常低效的。 You might want to find a way to use operator : as your main recursion engine instead.您可能想找到一种方法来使用 operator :作为您的主要递归引擎。 You will probably need a simpler hexDigits list like "0123456789ABCDEF" as mentioned in arrowd's answer.您可能需要一个更简单的hexDigits列表,如箭头的答案中提到的"0123456789ABCDEF"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM