键入与Word8和Int相关的错误

时间:2011-10-07 23:10:25

标签: haskell

尝试将字节字符串转换为十六进制ascii字符串显示

wordtoascii :: Int -> String
wordtoascii y =
  showIntAtBase 16 intToDigit ( fromEnum  y) ""

bs2string :: Data.ByteString.ByteString -> String
bs2string bs = do
  Prelude.map( wordtoascii,
               (unpack bs))

输入错误:

Couldn't match expected type `a -> b'
       against inferred type `(Int -> String, [GHC.Word.Word8])'
In the first argument of `Prelude.map', namely
    `(wordtoascii, (unpack bs))'
In the expression: Prelude.map (wordtoascii, (unpack bs))
In the expression: do { Prelude.map (wordtoascii, (unpack bs)) }

2 个答案:

答案 0 :(得分:4)

这不是您认为的语法。

Prelude.map( wordtoascii,
            (unpack bs))

这与:

相同
let x = (wordtoascii, unpack bs)
in map x

删除括号和逗号。

map wordtoascii (unpack bs)

然而,这也是错误的。因为上述表达式的类型是[String],而不是String。您需要concatMap,类似于map,但将结果拼接在一个字符串中。

concatMap wordtoascii (unpack bs)

或者,甚至更好,

bs2string = concatMap wordtoascii . unpack

逗号用于创建元组,列表和记录。例如,(1, 7) :: (Int, Int)可以是笛卡尔坐标。逗号不会出现在函数调用中。

通常,ByteString仅作为限定导入导入,因为许多函数与Prelude冲突。这样就不需要对碰撞的函数进行Prelude.限定。

import qualified Data.ByteString as S
bs2string = map wordtoascii . S.unpack

S代表StrictBS也是一种常见的选择,它代表Bytestring(严格)。

答案 1 :(得分:3)

Dietrich解释了你的代码的主要问题。但是,还存在unpack返回Word8列表且您的代码需要Int的问题。只需放宽wordtoascii

的类型签名即可解决此问题
> let wordtoascii y = showIntAtBase 16 intToDigit ( fromEnum  y) ""
> :t wordtoascii
wordtoascii :: Enum a => a -> String

Word8Enum的一个实例,因此使用此类型签名,您可以直接使用它。