[ create a new paste ] login | about

Link: http://codepad.org/h6g1sng7    [ raw code | fork ]

Plain Text, pasted on Sep 2:
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE ScopedTypeVariables #-}

module BitField where

import Control.Monad
import Control.Applicative
import Data.Bits
import Foreign.Ptr
import Foreign.Storable hiding (sizeOf)
import Data.StateVar

class BitField bitField where
   sizeOf         :: bitField -> Int
   --belongsTo      :: (Storable a, Bits a) => bitField -> a
   startPosition  :: bitField -> Int
   cSymbol        :: (Storable a, Bits a) => bitField -> Ptr a
   -- the below definition gives ambiguous type variable errors
   --valueOf      :: forall a . (Storable a, Bits a) => bitField -> IO a
   --valueOf      =  peek . cSymbol
   value          :: bitField -> IO [Bool]
   value n =
      do let v = makeStateVar (peek $ cSymbol n) (poke $ cSymbol n)
         x <- get v
         let bits :: Bits a => a -> Int -> Int -> [Bool]
             bits _ _        0   = []
             bits n position len = (testBit n position)
                                   : bits n (succ position) (pred len)
         return $ bits x (startPosition n) (sizeOf n)
   addBit         :: (Storable a, Bits a) =>
                     bitField -> Int -> Bool -> IO a
   addBit n pos flag
      | pos >= (sizeOf n) = error $ "bit Position: "
                                          ++ show pos
                                          ++ " >= (sizeOf n) :"
                                          ++ show (sizeOf n)
      | flag                   = value setBit
      | otherwise              = value clearBit
      where valueOf     = peek . cSymbol
            value f     = -- valueOf n
                           -- >>= (\x -> return $ f x pos)
                           -- could use the below instead of the above
                           (flip f pos) <$> (valueOf n)
                           >>= poke (cSymbol n)
                           >>= (\_ -> valueOf n)
   addBits      :: (Storable a, Bits a) => bitField -> [Bool] -> IO a
   addBits n flags
      | (length flags) > (sizeOf n)
         = error $ "(length flags) "          ++ show (length flags)
                   ++ " > (sizeOf n) :" ++ show (sizeOf n)
      | otherwise
         = zipWithM (addBit n) [0..] flags >>= (\x -> return $ last x)



Create a new paste based on this one


Comments: