Short Code
One of the complaints I’ve heard about Haskell is that it makes your code shorter. I’m not quite sure how that’s a bad thing, but it occurred to me while looking at a algorithm I wrote in Ruby.
puts $_.chomp.gsub(/../) { |b| b.hex.to_s + "."}.chop
The algorithm takes an IP address compactly represented in hex and returns the dotted decimal form.
Parsec is wonderful! I’ve been using it for a tetrinet protocol decoder so that was the first thing on my mind.
main = do
(h:_) <- getArgs
case parse (count 4 hexbyte) "Arguments" h of
Right r -> putStrLn $ tail $ concatMap (('.':) . show) r
Left e -> fail $ "Invalid input\n" ++ (show e)
hexbyte :: Parser Int
hexbyte = count 2 hexDigit >>= return . read . ('0':) . ('x':)
Which seems fairly easy to follow and has some error reporting free from Parsec, but I figure a parser library might be overkill for this task.
Turning to more “raw” Haskell, mostly the useful functions in the Data.List library, gives
main = getArgs >>= putStrLn . concat . intersperse "." .
map (show . readByte) . unfoldr lf . head
where
readByte :: String -> Int
readByte = read . ('0':) . ('x':)
lf [] = Nothing
lf t = Just $ splitAt 2 t
They’re all following approximately the same algorithm of a mapping on every two characters. However the gsub(/../) { |b| ... } appears to be a very compact notation which I have been unable to match.