Skip to content

Instantly share code, notes, and snippets.

@bos
Last active October 18, 2016 13:56
Show Gist options
  • Save bos/6986451 to your computer and use it in GitHub Desktop.
Save bos/6986451 to your computer and use it in GitHub Desktop.
A proof-of-concept of a new approach to encoding JSON values for aeson.
{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances,
OverloadedStrings #-}
import Data.Monoid (Monoid(..), (<>))
import Data.String (IsString(..))
import Data.Text (Text)
import Data.Text.Lazy.Builder (Builder, singleton)
import qualified Data.Text.Lazy.Builder as Bld
import qualified Data.Text.Lazy.Builder.Int as Bld
-- The phantom type here allows us to say "I am encoding a value of
-- type x".
data Build a = Build {
_count :: {-# UNPACK #-} !Int
, run :: Builder
}
instance Show (Build a) where
show = show . run
data Object
data Array
data Mixed
object :: Build Object -> Build Object
object (Build 0 _) = build "{}"
object (Build _ kvs) = build $ singleton '{' <> kvs <> singleton '}'
array :: Build a -> Build Array
array (Build 0 _) = build "[]"
array (Build _ vs) = build $ singleton '[' <> vs <> singleton ']'
instance Monoid (Build a) where
mempty = Build 0 mempty
mappend (Build i a) (Build j b)
| ij > 1 = Build ij (a <> singleton ',' <> b)
| otherwise = Build ij (a <> b)
where ij = i + j
instance IsString (Build Text) where
fromString = string
instance IsString (Build Mixed) where
fromString = build . Bld.fromString
(<:>) :: Build Text -> Build a -> Build Object
k <:> v = Build 1 (run k <> ":" <> run v)
int :: Integral a => a -> Build a
int = build . Bld.decimal
text :: Text -> Build Text
text = build . Bld.fromText
string :: String -> Build Text
string = build . Bld.fromString
build :: Builder -> Build a
build = Build 1
mixed :: Build a -> Build Mixed
mixed (Build a b) = Build a b
@lpsmith
Copy link

lpsmith commented Oct 16, 2013

Err, I meant, how common would it be to want two definitions, one to get a value, and the other to get a builder, due to the differing time/space complexities of the implementations?

@basvandijk
Copy link

@lpsmith FYI: I began experimenting with this approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment