Saturday, March 16, 2013

HASKELL JSON

HASKELL JSON

REVISED: Wednesday, January 24, 2024




Haskell JSON.

I.  HASKELL JSON

JavaScript Object Notation (JSON) language is a lightweight data-interchange format for storing and transmitting structured data over a network connection.

JSON supports four basic types of value: strings, numbers, booleans, and a special value named null.

A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string. If we want to construct a JSON string, we must provide a String value as an argument to the JString constructor.

A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.

An array is an ordered collection of values. An array begins with [ left bracket and ends with ] right bracket. Values are separated by , comma.

Whitespace can be inserted between any pair of tokens. Excepting a few encoding details, that completely describes the language.

The language provides two compound types: an array is an ordered sequence of values, and an object is an unordered collection of name value pairs. The names in an object are always strings; the values in an object or array can be of any type.

II.  HASKELL JSON EXAMPLE

A. SAVE HASKELL JSON EXAMPLE

"Copy Paste" the following module into your text editor and "File, Save As" MyJSON.hs to your working directory:

module MyJSON     -- Haskell representation of JSON's types.
        (
           JValue(..)
        ,  getString
        ,  getInt
        ,  getDouble
        ,  getBool
        ,  getObject
        ,  getArray
        ,  isNull
       )  where

data JValue = JString String   -- JString constructor requires String argument.
                    | JNumber Double
                    | JBool Bool
                    | JNull
                    | JObject [(String, JValue)]
                    | JArray [JValue]
                      deriving (Eq, Ord, Show)
 
getString :: JValue -> Maybe String
getString (JString s) = Just s
getString _                = Nothing

getInt (JNumber n) = Just (truncate n)
getInt _                   = Nothing

getDouble (JNumber n) = Just n
getDouble _                   = Nothing

getBool (JBool b) = Just b
getBool _             = Nothing

getObject (JObject o) = Just o
getObject _                 = Nothing

getArray (JArray a) = Just a
getArray _               = Nothing

isNull v                    = v == JNull

B. LOAD HASKELL JSON EXAMPLE

Load the above file MyJSON.hs into GHCi as shown below:

Prelude>  :load MyJSON.hs
[1 of 1] Compiling MyJSON       ( MyJSON.hs, interpreted )
Ok, modules loaded: MyJSON.
Prelude>

C. COMPILE HASKELL JSON EXAMPLE

The -c option tells GHC to only generate object code. If we were to omit the -c option, the compiler would attempt linking, generating a complete executable. That would fail, because we have not written a main function, which GHC calls to start the execution of a standalone program.

Prelude>  :! ghc -c "MyJSON.hs"
Prelude>  

After GHC completes, if we list the contents of the directory, it should contain two new files: MyJSON.hi and MyJSON.o. The former is an interface file, in which GHC stores information about the names exported from our module in machine-readable form. The latter is an object file, which contains the generated machine code.

D. SAVE HASKELL MAIN FUNCTION EXAMPLE

"Copy Paste" the following module into your text editor and "File, Save As" Main.hs to your working directory:

module Main where

import MyJSON     -- GHC will locate MyJSON module in working directory.

main = print (JObject [("Hello", JNumber 1), ("JSON", JBool False)])

E. LOAD HASKELL MAIN FUNCTION EXAMPLE

Load the above module Main.hs  into GHCi as shown below:

Prelude>  :load Main.hs
[2 of 2] Compiling Main             ( Main.hs, interpreted )
Ok, modules loaded: Main, MyJSON.
Prelude> 

F. COMPILE HASKELL MAIN FUNCTION EXAMPLE

We are omitting the -c option when we invoke GHC, so it will attempt to link, generate an executable. As our command line suggests, GHC is perfectly able to both compile source files and link an executable in a single invocation.

We pass GHC a new option, -o, which takes one argument: this is the name of the executable, object file, output file, that GHC should create. Here, we have decided to name the program testJSON. On Windows, the program will have the suffix .exe, but on Unix variants there will not be a suffix.

Finally, we supply the name of our new source file, Main.hs.

Prelude>  :! ghc  -o testJSON Main.hs   -- GHC will locate module in working directory.
[2 of 2] Compiling Main             ( Main.hs, Main.o )
Linking testJSON.exe ...
Prelude>  

When compiling, if GHC notices that it has already compiled a source file into an object file, it will only recompile the source file if we have modified it.

G. RUN HASKELL MAIN FUNCTION EXAMPLE

Once GHC has finished compiling and linking our simple program, we can run it from the command line as follows:

Prelude>  :load Main.hs
Ok, modules loaded: Main, MyJSON.
Prelude>

Prelude>  main
JObject [("Hello",JNumber 1.0),("JSON",JBool False)]
it :: ()
Prelude>  

III. REFERENCES

Bird, R. (2015). Thinking Functionally with Haskell. Cambridge, England: Cambridge University Press.

Davie, A. (1992). Introduction to Functional Programming Systems Using Haskell. Cambridge, England: Cambridge University Press.

Goerzen, J. & O'Sullivan, B. &  Stewart, D. (2008). Real World Haskell. Sebastopol, CA: O'Reilly Media, Inc.

Hutton, G. (2007). Programming in Haskell. New York: Cambridge University Press.

Lipovača, M. (2011). Learn You a Haskell for Great Good!: A Beginner's Guide. San Francisco, CA: No Starch Press, Inc.

Thompson, S. (2011). The Craft of Functional Programming. Edinburgh Gate, Harlow, England: Pearson Education Limited.

In this tutorial, you have received an introduction to Haskell JSON.