packages feed

memcached-0.1.2: Demo.lhs

Memcached interface.
Copyright (C) 2005 Evan Martin <martine@danga.com>

This program demonstrates the main use of the haskell-memcached API.
It's runnable directly if you have a server running on localhost:11211.

We first import the "Memcache" type class directly as well as all the
functions qualified.  The latter two imports will be explained below.

> import Network.Memcache(Memcache)
> import qualified Network.Memcache
> import Network.Memcache.Protocol as Single
> import Network.Memcache.Serializable(Serializable(..))

For this demonstration, we only use a single server.  But working with
a server pool ought to be transparent, as both single servers and the
pool are instances of the "Memcache" type class.

> main = do
>   server <- Single.connect "localhost" 11211
>   simpleDemo server
>   serializeDemo server
>   Single.disconnect server

> simpleDemo :: (Memcache mc) => mc -> IO ()
> simpleDemo memcache = do

When setting/getting keys, Haskell must be able to infer their type.
Typically, context will determine this, but if it doesn't you need
to annotate.

>   let foo = 3 :: Int
>   success <- Network.Memcache.set memcache "foo" foo
>   putStrLn ("Setting foo => 3: " ++ show success ++ ".")

Similarly for "get":
Generally this won't be a problem (the way you use the value will
make it specific) but it means that a naive "get" followed by a
"print" won't work -- there's no way to know whether you were trying
to get an Int or a String.
 
>   foo' <- Network.Memcache.get memcache "foo"
>   case foo' of
>     Nothing -> putStrLn "Retrieving foo: expired from cache?"
>     Just v  -> putStrLn ("Cached value for foo is " ++ show (v::Int) ++ ".")



By implementing the "serializable" class, you can serialize more complicated
data structures directly.  Suppose we had a "User" record that contained
information about a user that we wanted to be able to retrieve quickly.

> data User = User {
>   username :: String,
>   fontsize :: Int
> } deriving Show

For this simple type we can stringify it as just "username fontsize".
For more complicated data, you can do whatever crazy bitpacking necessary.

> instance Serializable User where
>   toString (User username fontsize) = username ++ " " ++ (show fontsize)
>   fromString str = case words str of
>                      (a:b:[]) -> Just (User a (read b))
>                      _        -> Nothing

> serializeDemo :: (Memcache mc) => mc -> IO ()
> serializeDemo memcache = do
>   let fred = User "fred" 24    -- fred likes large fonts
>   Network.Memcache.set memcache "u:fred" fred

>   fred' <- Network.Memcache.get memcache "u:fred"
>   putStrLn ("Fred is " ++ show (fred' :: Maybe User))

>   invalid <- Network.Memcache.get memcache "this key doesn't exist"
>   putStrLn ("Unknown returns: " ++ show (invalid :: Maybe User))


vim: set ts=2 sw=2 et :