úÎÂēC)      !"#$%&'("non-portable (uses GHC extensions)lemmih@gmail.comNoneGTo ensure that no-one reads or writes values without handling versions 2 correct, it is necessary to restrict access to   and  .  This is where * enters the picture. It allows you to put < values in to a container but not to take them out again. A simple numeric version id. CThe centerpiece of this library. Defines a version for a data type , together with how it should be serialized/parsed. !Users should define instances of  for their types  even though   and   can't be used directly.  To serialize/parse a data type using , see   and . The version of the type. FOnly used as a key so it must be unique (this is checked at run-time)  but doesn''t have to be sequential or continuous. The default version is '0'. <The kind specifies how versions are dealt with. By default, 2 values are tagged with their version id and don' t have any  previous versions. See  and the much less used  !. GThis method defines how a value should be parsed without also worrying M about writing out the version tag. This function cannot be used directly.  One should use  , instead. HThis method defines how a value should be parsed without worrying about K previous versions or migrations. This function cannot be used directly.  One should use  , instead. )0Internal function that should not be overrided.   Consistent' iff the version history is consistent 5 (i.e. there are no duplicate version numbers) and % the chain of migrations is valid. /This function is in the typeclass so that this : information is calculated only once during the program " lifetime, instead of everytime  or  is  used. Version profile. 1The name of the type. This is only used in error  message strings. 1 Feel free to leave undefined in your instances. 7Wrapper for data that was saved without a version tag. AThe kind of a data type determines how it is tagged (if at all). Primitives kinds (see ! ) are not tagged with a version * id and hence cannot be extended later. Extensions (see %) tells the system that there exists C a previous version of the data type which should be migrated if  needed. ?There is also a default kind which is neither primitive nor is $ an extension of a previous type. RThis is a wrapper type used migrating backwards in the chain of compatible types. 8The central mechanism for dealing with version control. :This type class specifies what data migrations can happen  and how they happen. This is the type we'1re extending. Each type capable of migration can  only extend one other type. FThis method specifies how to migrate from the older type to the newer G one. It will never be necessary to use this function manually as it 0 all taken care of internally in the library. JParse a version tagged data type and then migrate it to the desired type. L Any serialized value has been extended by the return type can be parsed. JParse a version tag and return the corresponding migrated parser. This is I useful when you can prove that multiple values have the same version.  See . ISerialize a data type by first writing out its version tag. This is much " simpler than the corresponding  since previous versions don't  come into play. KSerialize the version tag and return the associated putter. This is useful ? when serializing multiple values with the same version. See . :The extended_base kind lets the system know that there is - at least one future version of this type. :The extended_base kind lets the system know that there is - at least one future version of this type. 6The extension kind lets the system know that there is A at least one previous version of this type. A given data type < can only extend a single other data type. However, it is @ perfectly fine to build chains of extensions. The migrations / between each step is handled automatically. ,The default kind. Does not extend any type. !Primitive kinds aren':t version tagged. This kind is used for small or built-in  types that won't change such as * or +. "+Place a value in an unbreakable container. F,-./01234 ) 56789: !;"<=>?@ABCDEFGHIJKLMD,-./01234 ) 56789: !;"<=>?@ABCDEFGHIJK),-.0/1234 ) 87659: !;"<=>?@ABCDEFGHIJKLMNone#Derive an instance of . When serializing, we put a Word8 describing the 3 constructor (if the data type has more than one < constructor). For each type used in the constructor, we  call + (which immediately serializes the version > of the type). Then, for each field in the constructor, we ; use one of the put functions obtained in the last step. ;For example, given the data type and the declaration below   data T0 b = T0 b Int deriveSafeCopy 1 'base ''T0  we generate   %instance (SafeCopy a, SafeCopy b) =>  SafeCopy (T0 b) where 2 putCopy (T0 arg1 arg2) = contain $ do put_b < - getSafePut 2 put_Int < - getSafePut 7 put_b arg1 7 put_Int arg2 4 return () # getCopy = contain $ do get_b < - getSafeGet # get_Int < - getSafeGet % return T0 <*> get_b <*> get_Int  version = 1  kind = base >And, should we create another data type as a newer version of T0 , such as   data T a b = C a a | D b Int deriveSafeCopy 2 ' extension ''T  -instance SafeCopy b => Migrate (T a b) where " type MigrateFrom (T a b) = T0 b  migrate (T0 b i) = D b i  we generate   %instance (SafeCopy a, SafeCopy b) =>  SafeCopy (T a b) where 4 putCopy (C arg1 arg2) = contain $ do putWord8 0 / put_a < - getSafePut 4 put_a arg1 4 put_a arg2 3 return () 4 putCopy (D arg1 arg2) = contain $ do putWord8 1 1 put_b < - getSafePut 1 put_Int < - getSafePut 6 put_b arg1 6 put_Int arg2 3 return ()  getCopy = contain $ do tag < - getWord8 ' case tag of + 0 -> do get_a < - getSafeGet . return C <*> get_a <*> get_a - 1 -> do get_b < - getSafeGet - get_Int < - getSafeGet . return D <*> get_b <*> get_Int ) _ -> fail $ "Could not identify tag \"" ++ 5 show tag ++ "\" for type Main.T " ++ ) "that has only 2 constructors. " ++ ) "Maybe your data is corrupted?"  version = 2  kind = extension <Note that by using getSafePut, we saved 4 bytes in the case  of the C constructor. For D and T0 , we didn't save ? anything. The instance derived by this function always use 0 at most the same space as those generated by  %, but never more (as we don't call  'getSafePut'/'getSafeGet' for types that aren' t needed). Note that you may use % with one ! version of your data type and # in another ! version without any problems. %Derive an instance of . The instance derived by 4 this function is simpler than the one derived by  # in that we always use  and   (instead of  and ). When serializing, we put a Word8 describing the @ constructor (if the data type has more than one constructor) 2 and, for each field of the constructor, we use . ;For example, given the data type and the declaration below   data T a b = C a a | D b Int deriveSafeCopySimple 1 'base ''T  we generate   %instance (SafeCopy a, SafeCopy b) =>  SafeCopy (T a b) where 4 putCopy (C arg1 arg2) = contain $ do putWord8 0 6 safePut arg1 6 safePut arg2 3 return () 4 putCopy (D arg1 arg2) = contain $ do putWord8 1 6 safePut arg1 6 safePut arg2 3 return ()  getCopy = contain $ do tag < - getWord8 ' case tag of . 0 -> do return C <*> safeGet <*> safeGet . 1 -> do return D <*> safeGet <*> safeGet ) _ -> fail $ "Could not identify tag \"" ++ 5 show tag ++ "\" for type Main.T " ++ ) "that has only 2 constructors. " ++ ) "Maybe your data is corrupted?"  version = 1  kind = base :Using this simpler instance means that you may spend more ? bytes when serializing data. On the other hand, it is more > straightforward and may match any other format you used in  the past. Note that you may use # with one version of  your data type and % in another version  without any problems. 'Derive an instance of . The instance derived by @ this function should be compatible with the instance derived  by the module Happstack.Data.SerializeTH of the  happstack-data" package. The instances use only   and ! (as do the instances created by  %), but we also always write a Word8 ! tag, even if the data type isn't a sum type. ;For example, given the data type and the declaration below   data T0 b = T0 b Int deriveSafeCopy 1 'base ''T0  we generate   %instance (SafeCopy a, SafeCopy b) =>  SafeCopy (T0 b) where 5 putCopy (T0 arg1 arg2) = contain $ do putWord8 0 7 safePut arg1 7 safePut arg2 4 return ()  getCopy = contain $ do tag < - getWord8 ' case tag of / 0 -> do return T0 <*> safeGet <*> safeGet ) _ -> fail $ "Could not identify tag \"" ++ 5 show tag ++ "\" for type Main.T0 " ++ ) "that has only 1 constructors. " ++ ) "Maybe your data is corrupted?"  version = 1  kind = base 9This instance always consumes at least the same space as  # or %, but may use more @ because of the useless tag. So we recomend using it only if > you really need to read a previous version in this format,  and not for newer versions. Note that you may use # with one version of  your data type and ' in another version  without any problems. N;Follow type synonyms. This allows us to see, for example,  that [Char] and String$ are the same type and we just need  to call  or  once for both. OPQR#$%&'(STUVWXNYZ[\#$%&'(ORQP#$%&'(STUVWXNYZ[\None<]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜]^_`a<]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜"non-portable (uses GHC extensions)lemmih@gmail.comNone)  !"#$%&'()  "#$%&'(!™      !"#$%&'()*+,-.,-/00123 4 56789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_]`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™safecopy-0.8.2 Data.SafeCopyData.SafeCopy.SafeCopyData.SafeCopy.DeriveData.SafeCopy.InstancesProfileprofileCurrentVersionprofileSupportedVersionsInvalidProfilePrimitiveProfile ContainedVersionSafeCopyversionkindgetCopyputCopy objectProfile errorTypeNamePrim getPrimitiveKindReverse unReverseMigrate MigrateFrommigratesafeGet getSafeGetsafePut getSafePutextended_extension extended_base extensionbase primitivecontainderiveSafeCopyderiveSafeCopyIndexedTypederiveSafeCopySimplederiveSafeCopySimpleIndexedTypederiveSafeCopyHappstackData&deriveSafeCopyHappstackDataIndexedTypeinternalConsistencyghc-prim GHC.TypesIntBoolProxy Consistency NotConsistent Consistent unsafeUnPack unVersionExtendedExtendsBase Primitive isPrimitiveconstructGetterFromVersion castVersion mkProfileavailableVersionsgetForwardKind validChaincheckConsistencycomputeConsistencyisObviouslyConsistentproxyFromConsistency proxyFromKindconsistentFromProxyversionFromProxyversionFromKindversionFromReverseKind kindFromProxymkProxy asProxyType$fSerializeVersion $fNumVersionfollowSynonyms DeriveType HappstackDataSimpleNormalforceTaginternalDeriveSafeCopy!internalDeriveSafeCopyIndexedType mkPutCopy mkGetCopymkSafeFunctionsconSizeconNameconTypestypeNameiarray_getCopyiarray_putCopy typeName1 typeName2$fSafeCopyCalendarTime$fSafeCopyMonth $fSafeCopyDay$fSafeCopyTimeDiff$fSafeCopyClockTime$fSafeCopyAbsoluteTime$fSafeCopyZonedTime$fSafeCopyLocalTime$fSafeCopyTimeZone$fSafeCopyTimeOfDay$fSafeCopyNominalDiffTime$fSafeCopyUTCTime$fSafeCopyUniversalTime$fSafeCopyDiffTime$fSafeCopyDay0$fSafeCopyText$fSafeCopyText0$fSafeCopyEither$fSafeCopyBool $fSafeCopy()$fSafeCopyFixed$fSafeCopyRatio$fSafeCopyInt64$fSafeCopyInt32$fSafeCopyInt16$fSafeCopyInt8$fSafeCopyOrdering$fSafeCopyWord64$fSafeCopyWord32$fSafeCopyWord16$fSafeCopyWord8$fSafeCopyChar$fSafeCopyByteString$fSafeCopyByteString0$fSafeCopyDouble$fSafeCopyFloat$fSafeCopyInteger $fSafeCopyInt$fSafeCopy(,,,,,,)$fSafeCopy(,,,,,)$fSafeCopy(,,,,)$fSafeCopy(,,,)$fSafeCopy(,,) $fSafeCopy(,)$fSafeCopyUArray$fSafeCopyArray$fSafeCopyTree $fSafeCopySeq$fSafeCopyIntSet$fSafeCopyIntMap $fSafeCopyMap $fSafeCopySet$fSafeCopyMaybe $fSafeCopy[]$fSafeCopyPrim