2012-08-09 101 views
3

(SRC http://hackage.haskell.org/packages/archive/safecopy/0.6.1/doc/html/Data-SafeCopy.html哈斯克爾safecopy例如

如果重命名聯繫人數據類型轉換數據Contacts_v0

type Name  = String 
type Address = String 
data Contacts = Contacts [(Name, Address)] 
instance SafeCopy Contacts where 
    putCopy (Contacts list) = contain $ safePut list 
    getCopy = contain $ Contacts <$> safeGet 

如何Contacts_v0假設被分配到舊的現有數據?

type Name = String 
type Address = String 
type Phone = String 

data Contacts_v0 = Contacts_v0 [(Name, Address)] 
instance SafeCopy Contacts_v0 where 
    putCopy (Contacts_v0 list) = contain $ safePut list 
    getCopy = contain $ Contacts_v0 <$> safeGet 

data Contact = Contact { name :: Name 
         , address :: Address 
         , phone :: Phone } 
instance SafeCopy Contact where 
    putCopy Contact{..} = contain $ do safePut name; safePut address; safePut phone 
    getCopy = contain $ Contact <$> safeGet <*> safeGet <*> safeGet 

data Contacts = Contacts [Contact] 
instance SafeCopy Contacts where 
    version = 2 
    kind = extension 
    putCopy (Contacts contacts) = contain $ safePut contacts 
    getCopy = contain $ Contacts <$> safeGet 

instance Migrate Contacts where 
    type MigrateFrom Contacts = Contacts_v0 
    migrate (Contacts_v0 contacts) = Contacts [ Contact{ name = name 
                 , address = address 
                 , phone = "" } 
               | (name, address) <- contacts ] 

從上面的庫文檔我試圖做到這一點。

{-# LANGUAGE RecordWildCards, TypeFamilies #-} 
import Control.Applicative 
import Data.SafeCopy 

type Name = String 
type Address = String 
type Phone = String 

data Contacts = Contacts [(Name, Address)] deriving (Show) 
instance SafeCopy Contacts where 
    putCopy (Contacts list) = contain $ safePut list 
    getCopy = contain $ Contacts <$> safeGet 

data Contacts_v0 = Contacts_v0 [(Name, Address)] deriving (Show) 
instance SafeCopy Contacts_v0 where 
    putCopy (Contacts_v0 list) = contain $ safePut list 
    getCopy = contain $ Contacts_v0 <$> safeGet 

data Contact = Contact { name :: Name, address :: Address, phone :: Phone } deriving (Show) 
instance SafeCopy Contact where 
    putCopy Contact{..} = contain $ do safePut name; safePut address; safePut phone 
    getCopy = contain $ Contact <$> safeGet <*> safeGet <*> safeGet 

{- 
data Contacts = Contacts [Contact] 
instance SafeCopy Contacts where 
    version = 2 
    kind = extension 
    putCopy (Contacts contacts) = contain $ safePut contacts 
    getCopy = contain $ Contacts <$> safeGet 

instance Migrate Contacts where 
    type MigrateFrom Contacts = Contacts_v0 
    migrate (Contacts_v0 contacts) = Contacts [ Contact{ name = name, address = address, phone = "" } 
               | (name, address) <- contacts ] 
-} 

main :: IO() 
main = do 
    let test = Contacts [("gert","home")] 
    print test 
    --let testNew = how do you migrate test using migrate? 
    --print testNew 

注意,它將使我更有意義,如果他們改名爲新的一個Contacts_v2代替重新命名舊的。

也許我應該改寫這個問題,何時safecopy有用?

+0

什麼! -1爲什麼......? – 2012-08-09 18:27:05

+0

你能否提出一個明確的問題,並在文中給出一些關於你的問題的介紹? – Tarrasch 2012-08-09 18:33:01

+0

'Contacts_v0如何被分配到舊的已有數據?'不知道如何更清楚,在介紹中工作請稍候。 – 2012-08-09 18:58:08

回答

3
{-# LANGUAGE RecordWildCards, TypeFamilies#-} 
import Control.Applicative 
import Data.SafeCopy 
import Data.Binary 
import Data.Serialize.Get 
import Data.Serialize.Put 

type Name = String 
type Address = String 
type Phone = String 

data Contact = Contact { name :: Name, address :: Address, phone :: Phone } deriving (Show) 
instance Binary Contact where 
    put Contact{..} = do put name; put address; put phone 
    get = do name <- get; address <- get; phone <- get; return Contact{..} 
instance SafeCopy Contact where 
    putCopy Contact{..} = contain $ do safePut name; safePut address; safePut phone 
    getCopy = contain $ Contact <$> safeGet <*> safeGet <*> safeGet 

data Contacts = Contacts [Contact] deriving (Show) 
instance Binary Contacts where 
    put (Contacts set) = put set 
    get = fmap Contacts get 
instance SafeCopy Contacts where 
    version = 2 
    kind = extension 
    putCopy (Contacts contacts) = contain $ safePut contacts 
    getCopy = contain $ Contacts <$> safeGet 
instance Migrate Contacts where 
    type MigrateFrom Contacts = Contacts_v0 
    migrate (Contacts_v0 contacts) = Contacts[Contact{name=name,address=address,phone=""}|(name,address)<-contacts] 

data Contacts_v0 = Contacts_v0 [(Name, Address)] deriving (Show) 
instance Binary Contacts_v0 where 
    put (Contacts_v0 set) = put set 
    get = fmap Contacts_v0 get 
instance SafeCopy Contacts_v0 where 
    putCopy (Contacts_v0 list) = contain $ safePut list 
    getCopy = contain $ Contacts_v0 <$> safeGet 

main :: IO() 
main = do 
    -- 
    -- instance Binary 
    -- 
    let c' = Contacts[Contact{name="gert",address="home",phone="test"},Contact{name="gert2",address="home2",phone="test2"}] 
    let e' = encode c' 
    print e' 
    let d' = decode e' 
    print (d':: Contacts) 

    let c = Contacts_v0 [("gert_v0","home_v0"),("gert2_v0","home2_v0")] 
    let e = encode c 
    print e 
    let d = decode e 
    print (d:: Contacts_v0) 
    --can not do print (d:: Contacts) meaning you are screwed 

    -- 
    -- instance SafeCopy 
    -- 
    let c'' = Contacts_v0 [("gert_v0","home_v0"),("gert2_v0","home2_v0")] 
    let e'' = runPut (safePut c'') 
    print e'' 
    let d'' = runGet safeGet e'' 
    case d'' of 
     Left _ -> print "error" 
     Right d'' -> print (d'':: Contacts) 
    --can do print (d:: Contacts) or print (d:: Contacts_v0) meaning you are safed