Skip to content

Instantly share code, notes, and snippets.

@phadej
Created December 25, 2014 15:08
Show Gist options
  • Save phadej/c41e7363f2819681bbe3 to your computer and use it in GitHub Desktop.
Save phadej/c41e7363f2819681bbe3 to your computer and use it in GitHub Desktop.
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative
import Control.Monad
import Data.Aeson
import Data.ByteString.Lazy as B -- imported so it's easy to work in ghci
import qualified Data.HashMap.Strict as HashMap
type DirectoryName = String
type DocumentName = String
type DocumentContent = String
data Document = Document DocumentName DocumentContent deriving Show
data Directory = Directory DirectoryName [DocumentOrDirectory] deriving Show
newtype DocumentOrDirectory = DocumentOrDirectory (Either Document Directory) deriving Show
-- "upcasts"
liftDocument :: Document -> DocumentOrDirectory
liftDocument = DocumentOrDirectory . Left
liftDirectory :: Directory -> DocumentOrDirectory
liftDirectory = DocumentOrDirectory . Right
-- ToJSON
instance ToJSON Document where
toJSON (Document name content) = object [ "document" .= object [
"name" .= name,
"content" .= content ]]
instance ToJSON Directory where
toJSON (Directory name content) = object [ "directory" .= object [
"name" .= name,
"content" .= content ]]
instance ToJSON DocumentOrDirectory where
toJSON (DocumentOrDirectory (Left d)) = toJSON d
toJSON (DocumentOrDirectory (Right d)) = toJSON d
-- Example data
document :: Document
document = Document "docname" "lorem"
directory :: Directory
directory = Directory "directory" [ liftDocument document, liftDocument document ]
dod1 :: DocumentOrDirectory
dod1 = liftDocument document
dod2 :: DocumentOrDirectory
dod2 = liftDirectory directory
-- FromJSON
instance FromJSON Document where
parseJSON (Object v) = maybe mzero parser $ HashMap.lookup "document" v
where parser (Object v') = Document <$> v' .: "name"
<*> v' .: "content"
parser _ = mzero
parseJSON _ = mzero
instance FromJSON Directory where
parseJSON (Object v) = maybe mzero parser $ HashMap.lookup "directory" v
where parser (Object v') = Directory <$> v' .: "name"
<*> v' .: "content"
parser _ = mzero
parseJSON _ = mzero
instance FromJSON DocumentOrDirectory where
parseJSON j = (liftDocument <$> parseJSON j) <|> (liftDirectory <$> parseJSON j)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment