2

I am trying to serialize a Contacts type but I am stuck at defining put and get?

import Control.Monad
import Data.Binary

type Name = String
type Address = String

data Contacts = Contacts [(Name, Address)] deriving (Show)
instance Binary Contacts where
    put (Contacts [(n,a)]) = do ...
    get = do ...

main :: IO ()
main = do
    let c = Contacts [("gert","home")]
    let e = encode c
    let d = decode e
    print d
Gert Cuykens
  • 6,845
  • 13
  • 50
  • 84
  • explain to me why for example questions like [this](http://stackoverflow.com/questions/3736576/how-to-get-the-current-mavensession-or-mavenexecutionrequest-from-a-plexus-compo) get +40 and mine -1? – Gert Cuykens Aug 10 '12 at 18:59
  • also is their anything in http://stackoverflow.com/faq that would make this a bad question? – Gert Cuykens Aug 10 '12 at 19:19
  • 1
    IMO your questions tend to be a bit vague and heavy on extraneous, somewhat domain-specific code (though this one isn't). I think you'd fare better by isolating a _programming question_ in more detail, rather than asking 'what is wrong with my code'. Check out a couple of [highly-voted questions tagged with haskell](http://stackoverflow.com/questions/tagged/haskell?sort=votes) to get an idea of what makes them successful. There is also the accurate http://stackoverflow.com/questions/how-to-ask. – jtobin Aug 10 '12 at 20:10
  • If you are new to haskell there is no way in hell you would go from http://code.haskell.org/binary/ to the answer I got. All the code I tried did not make any sense and would only confuse the question. If you google `haskell Data.Binary example` you will see even my own question is in the top 10 result because of the lack of other examples. If you do this for js java c c# bash... you get tons and tons of data to look at. – Gert Cuykens Aug 10 '12 at 21:08
  • And in the end it seem I merely asked for 2 lines of code to help me with. – Gert Cuykens Aug 10 '12 at 21:44

2 Answers2

4

Yes, you are stuck defining put and get. Does that answer your question?

type Name = String
type Address = String

data Contacts = Contacts [(Name, Address)] deriving (Show)
instance Binary Contacts
    put (Contacts [(n,a)]) = do ...
    get = do ...

Since there are already instances:

instance (Binary a) => Binary [a]
instance (Binary a, Binary b) => Binary (a,b)
instance Binary Char

You should just be able to trivially lift the underlying put and get routines:

instance Binary Contacts where
    put (Contacts set) = put set
    get = fmap Contacts get

So when you put contacts you just tell it to put the list of pairs of strings. When you want to deserialize the contacts you just get the underlying list and use the Contacts constructor.

Thomas M. DuBuisson
  • 64,245
  • 7
  • 109
  • 166
  • detecting a little sarcasm here :) anyway need time to decode answer just a moment, I am sure its correct thx. – Gert Cuykens Aug 10 '12 at 17:00
  • I must use Data.Serialize then `instance Serialize Contacts` and not `instance Binary Contacts` right? – Gert Cuykens Aug 10 '12 at 17:11
  • Can you reflect that in the answer pleas that Data.Binary is too low level and recommend using Serialize? Or did i miss the point? – Gert Cuykens Aug 10 '12 at 17:14
  • Gert: I editted to stick with Binary. `Binary` should work fine for you, I just usually use `Serialize` (from the `cereal` package) as it better fits my needs. – Thomas M. DuBuisson Aug 10 '12 at 17:42
  • thx one final thing that is confusing for me `print [("gert","home")]` works but `print d` does not, why? – Gert Cuykens Aug 10 '12 at 17:56
  • 2
    When you decode something you need to be explicit about the type (decode is of type `ByteString -> a` so what is `a`?). For your use, try `print (d :: Contacts)` or put the type on the `let` statement. – Thomas M. DuBuisson Aug 10 '12 at 18:08
4

Adding more simple examples to prevent other noobs from suffering like me :)

{-# LANGUAGE RecordWildCards #-}   
import Data.Binary

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

data Contacts = Contacts [(Name, Address)] deriving (Show)
instance Binary Contacts where
    put (Contacts set) = put set
    get = fmap Contacts get

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{..}

main :: IO ()
main = do
    let c = Contacts [("gert","home"),("gert2","home2")]
    let e = encode c
    print e
    let d = decode e
    print (d:: Contacts)

    let c' = Contact{name="gert",address="home",phone="test"}
    let e' = encode c'
    print e'
    let d' = decode e'
    print (d':: Contact)
Gert Cuykens
  • 6,845
  • 13
  • 50
  • 84