2011-10-07 49 views
1

试图字节字符串转换为十六进制的ASCII字符串显示有关Word8和Int

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)) } 

回答

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 

逗号是用于创建元组,列表和记录。例如,​​可能是笛卡尔坐标。逗号不会出现在函数调用中。

通常,ByteString仅作为合格的导入导入,因为如此多的函数与Prelude冲突。这消除了对冲突的功能进行Prelude.认证的必要性。

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

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

+0

有趣...在我修复后,我仍然得到一个转换错误,因为“无法匹配 - 预期的Int对于intferred类型GHC.Word.Word8”。 –

+0

那么,使用'(wordtoascii。fromIntegral)'而不是'wordtoascii'。 'fromIntegral'函数非常非常方便。它也很好地优化。 –

3

Dietrich解释了您的代码的主要问题。但是,也有unpack返回Word8列表的问题,您的代码需要Int。这可以通过固定只是放松的wordtoascii类型签名:

> let wordtoascii y = showIntAtBase 16 intToDigit (fromEnum y) "" 
> :t wordtoascii 
wordtoascii :: Enum a => a -> String 

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

+0

谢谢!现在正在工作。 –

相关问题