3
\$\begingroup\$

I wrote a simple program in Haskell which takes Hex input from stdin, converts the input to ascii and writes it to stdout. An example use:

$ echo -n '48656c6c6f2c2043522e534521' | unhex
Hello, CR.SE!

And here the source code:

import qualified Data.ByteString as B
import Data.Bits
import Data.Word

unhex :: [Word8] -> [Word8]
unhex [] = []
unhex (x:[]) = error "invalid input length"
unhex (x:y:xs) = [(shiftL (hex2val x) 4) .|. (hex2val y)] ++ unhex xs
    where hex2val x =  hex2val' $ (x .|. 0x20) -- lowercase char
          hex2val' x 
        | x >= 48 && x < 48 + 10 =  0 + x - 48 -- 48 is '0' in ascii
        | x >= 97 && x < 97 +  6 = 10 + x - 97 -- 97 is 'a' in ascii
        | otherwise              = error "invalid hex input"

main = do
    input <- B.getContents
    B.putStrLn $ B.pack $ unhex $ B.unpack input

This is one of my first Haskell programs I wrote, would be interesting to get some feedback on how to accomplish this task more the "Haskell" way. I'd like to know if this kind of error reporting is appropriate.

\$\endgroup\$
2
\$\begingroup\$

Calling error is fine for a small program like this.

For more advanced error handling see the Failure page on HaskellWiki.


Some comments about your code:

unhex (x:[]) = error "invalid input length"

x is not used here, use this pattern instead: (_:[])

unhex (x:y:xs) = [(shiftL (hex2val x) 4) .|. (hex2val y)] ++ unhex xs

[x] ++ xs is usually written x : xs

hex2val' $ (x .|. 0x20)

$ is useless here.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.