Disclaimer: It's literally the second time I write in Haskell.
The purpose of this module is to provide some basic operations with IP addresses (and networks).
At the moment I only implemented the
successor operation, that returns a next address in the range if it exists.
192.168.1.0/24 it would return
192.168.1.255 (which is the last valid IP address in the given network) it would return
module Main where import Data.IP (IPv4, AddrRange(addr), fromIPv4, toIPv4, isMatchedTo, makeAddrRange) import Data.Bits (shiftL, shiftR, (.|.), (.&.)) import Data.List (foldl') import Text.Read (readMaybe) import qualified Safe as S parse :: String -> Maybe IPv4 parse = readMaybe toInt :: IPv4 -> Int toInt i = foldl' accum 0 (fromIPv4 i) where accum a v = (a `shiftL` 8) .|. v fromInt :: Int -> IPv4 fromInt i = toIPv4 $ map (\s -> (i `shiftR` s) .&. 0xff) [24, 16, 8, 0] addressesInNetwork :: AddrRange IPv4 -> [IPv4] addressesInNetwork i = takeWhile (`isMatchedTo` i) adds where net = toInt $ addr i adds = map (\s -> fromInt $ net + s) [0..] successor :: Int -> IPv4 -> Maybe IPv4 successor r a = S.headMay $ dropWhile (<= a) $ addressesInNetwork $ makeAddrRange a r net24 :: IPv4 -> Maybe IPv4 net24 = successor 24 main::IO() main = print $ parse "192.168.1.201" >>= net24
What I don't like: it just looks terrible. I look on it and see Perl, not Haskell.
Have I done something idiomatically wrong or my sense of beauty is broken?