[Haskell-cafe] How to compare PortNumbers or Bug in Network.Socket?

Stefan Schmidt stefanschmidt42 at googlemail.com
Thu Mar 12 17:44:40 EDT 2009


I want to compare two PortNumber-Values from the Network.Socket module 
and I think I've experienced some unexpected behavior of the derived 
ordering methods. I'm using the ghc-6.10.1 and the network library on a x86 32-Bit machine.

The following program creates two pairs of PortNumber values and 
compares them with each other.

module Main(main) where

import Network.Socket

-- Block A
p1 :: PortNumber
p1 = fromIntegral 9000
p2 :: PortNumber
p2 = fromIntegral 10000

-- Block B
pp1 :: PortNumber
pp1 = PortNum 9000
pp2 :: PortNumber
pp2 = PortNum 10000

main :: IO ()
   = do
     putStrLn $ "A - " ++ (show $ p1  > p2)
     putStrLn $ "B - " ++ (show $ pp1 > pp2)

On my machine, I get the result:

A - True
A - False

At the first glance, it seemed to me, that there is a bug in the 
fromIntegral Implementation. But after I looked into the code, I saw 
that fromIntegral calls the system function "htons" to change the byte 
order from my machine to the network byte order, which on my machine is 
different. Because of this the values 9000 and 10000 are transferred, so 
that their ordering changes.

Block B preservers this ordering, because the Constructor PortNum does 
not call htons, but since the byte order is wrong, I cannot use pp1 and 
pp2 to address port 9000 and 10000.

As a work around, I could convert two PortNumbers back to Int-Values 
before comparing them, but I think the ordering functions for the 
PortNumber-Type do not work as expected. Or am I wrong?

Stefan Schmidt

More information about the Haskell-Cafe mailing list