Working my way through Haskell and I'm trying to learn how to serialized to/from JSON.
I'm using aeson-0.8.0.2 & I'm stuck at basic decoding. Here's what I have:
file playground/aeson.hs:
{-# LANGUAGE OverloadedStrings #-}
import Data.Text
import Data.Aeson
data Person = Person
{ name :: Text
, age :: Int
} deriving Show
instance FromJSON Person where
parseJSON (Object v) = Person <$>
v .: "name" <*>
v .: "age"
parseJSON _ = mzero
main = do
let a = decode "{\"name\":\"Joe\",\"age\":12}" :: Maybe Person
print "aa"
ghc --make playground/aeson.hs yields:
[1 of 1] Compiling Main ( playground/aeson.hs, playground/aeson.o )
playground/aeson.hs:13:35: Not in scope: `'
playground/aeson.hs:14:40: Not in scope: `<*>'
playground/aeson.hs:17:28: Not in scope: `mzero'
- Any idea what I'm doing wrong?
- Why is OverloadedString needed here?
- Also, I have no idea what
<$>
,<*>
, ormzero
are supposed to mean; I'd appreciate tips on where I can read about any of these.
You need to import
Control.Applicative
andControl.Monad
to get<$>
,<*>
andmzero
.<$>
just an infix operator forfmap
, and<*>
is theApplicative
operator, you can think of it as a more generalized form offmap
for now.mzero
is defined for theMonadPlus
class, which is a class representing that aMonad
has the operationAnd a "monadic zero" element called
mzero
. The simplest example is for lists:Here
mzero
is being used to represent a failure to parse. For looking up symbols in the future, I recommend using hoogle or FP Complete's version. Once you find the symbol, read the documentation, the source, and look around for examples of its use on the internet. You'll learn a lot by looking for it yourself, although it'll take you a little while to get used to this kind of research.The
OverloadedStrings
extension is needed here because theAeson
library works with theText
type fromData.Text
instead of the built-inString
type. This extension lets you use string literals asText
instead ofString
, just as the numeric literal0
can be anInt
,Integer
,Float
,Double
,Complex
and other types.OverloadedStrings
makes string literals have typeText.String.IsString s => s
instead of justString
, so it makes it easy to use alternate string-y types.