1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE UndecidableInstances #-}
3{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE ScopedTypeVariables #-}
7module Control.Distributed.Process.Serializable
15 , SerializableDict(SerializableDict)
16 , TypeableDict(TypeableDict)
19import Data.Binary (Binary)
21#if MIN_VERSION_base(4,10,0)
22import Data.Typeable (Typeable)
23import Type.Reflection (typeRep)
24import Type.Reflection.Unsafe (TypeRep, typeRepFingerprint)
25#elif MIN_VERSION_base(4,7,0)
26import Data.Typeable (Typeable)
27import Data.Typeable.Internal (TypeRep(TypeRep), typeOf)
29import Data.Typeable (Typeable(..))
30import Data.Typeable.Internal (TypeRep(TypeRep))
33import Numeric (showHex)
34import Control.Exception (throw)
35import GHC.Fingerprint.Type (Fingerprint(..))
36import Data.ByteString (ByteString)
37import qualified Data.ByteString as BS
38import qualified Data.ByteString.Internal as BSI ( unsafeCreate, toForeignPtr )
39import Foreign.Storable (pokeByteOff, peekByteOff, sizeOf)
40import Foreign.ForeignPtr (withForeignPtr)
41import System.IO.Unsafe (unsafePerformIO)
43-- | Reification of 'Serializable' (see "Control.Distributed.Process.Closure")
44data SerializableDict a where
45 SerializableDict :: Serializable a => SerializableDict a
48-- | Reification of 'Typeable'.
49data TypeableDict a where
50 TypeableDict :: Typeable a => TypeableDict a
53-- | Objects that can be sent across the network
54class (Binary a, Typeable a) => Serializable a
55instance (Binary a, Typeable a) => Serializable a
57-- | Encode type representation as a bytestring
58encodeFingerprint :: Fingerprint -> ByteString
60 -- Since all CH nodes will run precisely the same binary, we don't have to
61 -- worry about cross-arch issues here (like endianness)
62 BSI.unsafeCreate sizeOfFingerprint $ \p -> pokeByteOff p 0 fp
64-- | Decode a bytestring into a fingerprint. Throws an IO exception on failure
65decodeFingerprint :: ByteString -> Fingerprint
67 | BS.length bs /= sizeOfFingerprint =
68 throw $ userError "decodeFingerprint: Invalid length"
69 | otherwise = unsafePerformIO $ do
70 let (fp, offset, _) = BSI.toForeignPtr bs
71 withForeignPtr fp $ \p -> peekByteOff p offset
73-- | Size of a fingerprint
74sizeOfFingerprint :: Int
75sizeOfFingerprint = sizeOf (undefined :: Fingerprint)
77-- | The fingerprint of the typeRep of the argument
78fingerprint :: forall a. Typeable a => a -> Fingerprint
79#if MIN_VERSION_base(4,10,0)
80fingerprint _ = typeRepFingerprint (typeRep :: TypeRep a)
81#elif MIN_VERSION_base(4,8,0)
82fingerprint a = let TypeRep fp _ _ _ = typeOf a in fp
84fingerprint a = let TypeRep fp _ _ = typeOf a in fp
87-- | Show fingerprint (for debugging purposes)
88showFingerprint :: Fingerprint -> ShowS
89showFingerprint (Fingerprint hi lo) =
90 showString "(" . showHex hi . showString "," . showHex lo . showString ")"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list