[Haskell-cafe] Efficient and type safe flag sets

Henning Thielemann lemming at henning-thielemann.de
Sun Nov 4 16:15:45 EST 2007


We have
  http://www.haskell.org/haskellwiki/EnumSet_EnumMap

Is there also an efficient implementation for bit sets that fit into a
machine word? This would be useful for foreign function interfaces.

E.g. where C defines

#define SND_SEQ_PORT_CAP_READ		(1<<0)	/**< readable from this port */
#define SND_SEQ_PORT_CAP_WRITE		(1<<1)	/**< writable to this port */

#define SND_SEQ_PORT_CAP_SYNC_READ	(1<<2)	/**< allow read subscriptions */
#define SND_SEQ_PORT_CAP_SYNC_WRITE	(1<<3)	/**< allow write subscriptions */


In Haskell we could define

module SndSeq

data PortCap = Read | Write | SyncRead | SyncWrite

bit32 :: Enum a => a -> FlagSet32 a
flags32 :: Enum a => [a] -> FlagSet32 a


In C we have to write
   foo (SND_SEQ_PORT_CAP_SYNC_READ | SND_SEQ_PORT_CAP_SYNC_READ)
 which is efficient but unsafe, because flags of the wrong sort or plain
numbers could be passed accidentally.

In Haskell we would write
   foo (flags32 [Read, SyncRead])

which is both efficient and safe, because
   foo :: FlagSet32 PortCap -> IO ()

(Given that constant expression evaluation works ...)


More information about the Haskell-Cafe mailing list