#haskell
#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)) }
Ответ №1:
Это не тот синтаксис, который вы думаете.
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
Расшифровывается как Strict
. BS
также является распространенным выбором, он расшифровывается как for Bytestring (строгий).
Комментарии:
1. Интересно… После того, как я исправлю это, я все равно получаю ошибку преобразования как «Не удалось сопоставить ожидаемый Int с введенным типом GHC.Word.Word8».
2. Ну, тогда используйте
(wordtoascii . fromIntegral)
вместоwordtoascii
.fromIntegral
Функция очень, очень удобная. Он также довольно хорошо оптимизирован.
Ответ №2:
Дитрих объяснил основную проблему с вашим кодом. Однако существует также проблема, которая unpack
возвращает список Word8
ожидаемых и ожидаемых вашим кодом Int
. Это можно исправить, просто ослабив сигнатуру типа wordtoascii
:
> let wordtoascii y = showIntAtBase 16 intToDigit ( fromEnum y) ""
> :t wordtoascii
wordtoascii :: Enum a => a -> String
Word8
является экземпляром Enum
, поэтому с сигнатурой этого типа вы можете использовать ее напрямую.