diff --git a/plist.cabal b/plist.cabal
--- a/plist.cabal
+++ b/plist.cabal
@@ -1,5 +1,5 @@
 name: plist
-version: 0.0.1
+version: 0.0.2
 cabal-version: -any
 build-type: Simple
 license: BSD3
diff --git a/src/Text/XML/Plist.hs b/src/Text/XML/Plist.hs
--- a/src/Text/XML/Plist.hs
+++ b/src/Text/XML/Plist.hs
@@ -20,7 +20,13 @@
 objectToPlist,
 plistToObject,
 objectToXml,
-xmlToObject
+xmlToObject,
+fromPlString,
+fromPlBool,
+fromPlInteger,
+fromPlReal,
+fromPlArray,
+fromPlDict
 
 ) where
 
diff --git a/src/Text/XML/Plist/PlObject.hs b/src/Text/XML/Plist/PlObject.hs
--- a/src/Text/XML/Plist/PlObject.hs
+++ b/src/Text/XML/Plist/PlObject.hs
@@ -14,7 +14,13 @@
 
 module Text.XML.Plist.PlObject (
 
-PlObject(..)
+PlObject(..),
+fromPlString,
+fromPlBool,
+fromPlInteger,
+fromPlReal,
+fromPlArray,
+fromPlDict
 
 ) where
 
@@ -39,4 +45,28 @@
     -- |date (ISO 8601, but currently it is not validated)
     PlDate String
     deriving Show
+
+fromPlString :: Monad m => PlObject -> m String
+fromPlString (PlString str) = return str
+fromPlString o = fail $ "not a string: " ++ show o
+
+fromPlBool :: Monad m => PlObject -> m Bool
+fromPlBool (PlBool bool) = return bool
+fromPlBool o = fail $ "not a bool: " ++ show o
+
+fromPlInteger :: Monad m => PlObject -> m Int
+fromPlInteger (PlInteger i) = return i
+fromPlInteger o = fail $ "not an integer: " ++ show o
+
+fromPlReal :: Monad m => PlObject -> m Double
+fromPlReal (PlReal r) = return r
+fromPlReal o = fail $ "not a real: " ++ show o
+
+fromPlArray :: Monad m => PlObject -> m [PlObject]
+fromPlArray (PlArray arr) = return arr
+fromPlArray o = fail $ "not an array: " ++ show o
+
+fromPlDict :: Monad m => PlObject -> m [(String, PlObject)]
+fromPlDict (PlDict d) = return d
+fromPlDict o = fail $ "not a dictionary: " ++ show o
 
diff --git a/src/Text/XML/Plist/Read.hs b/src/Text/XML/Plist/Read.hs
--- a/src/Text/XML/Plist/Read.hs
+++ b/src/Text/XML/Plist/Read.hs
@@ -35,7 +35,7 @@
         )
     if null res
         then fail $ "can't parse " ++ fileName
-        else return (res !! 0)
+        else return $ head res
 
 -- |Arrow that converts xml tree to 'PlObject'.
 -- Tree should contain at list one \"plist\" element.
@@ -50,8 +50,8 @@
 xmlToObject :: ArrowXml a => a XmlTree PlObject
 xmlToObject = choiceA [
     hasName "string" :-> (innerText >>> arr PlString),
-    hasName "true" :-> (constA $ PlBool True),
-    hasName "false" :-> (constA $ PlBool False),
+    hasName "true" :-> constA (PlBool True),
+    hasName "false" :-> constA (PlBool False),
     hasName "integer" :-> (innerText >>> arr (PlInteger . read)),
     hasName "real" :-> (innerText >>> arr (PlReal . read)),
     hasName "array" :-> (listA readArray >>> arr PlArray),
@@ -84,9 +84,9 @@
     xmlToObject
 
 innerText :: ArrowXml a => a XmlTree String
-innerText = single (
+innerText = withDefault (single (
     getChildren >>>
     isText >>>
     getText
-    )
+    )) ""
 
diff --git a/src/Text/XML/Plist/Write.hs b/src/Text/XML/Plist/Write.hs
--- a/src/Text/XML/Plist/Write.hs
+++ b/src/Text/XML/Plist/Write.hs
@@ -50,7 +50,7 @@
 objectToXml (PlArray objects) = selem "array" $ map objectToXml objects
 objectToXml (PlDict objects) = selem "dict" elems
     where
-    elems = foldr (++) [] $ map toXml objects
+    elems = concatMap toXml objects
     toXml (key, val) = [selem "key" [txt key], objectToXml val]
 objectToXml (PlData dat) = selem "data" [txt $ enc dat]
     where
