<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: haskell code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sun, 07 Sep 2008 01:47:47 GMT</pubDate>
    <description>DZone Snippets: haskell code</description>
    <item>
      <title>Convert radix in haskell: </title>
      <link>http://snippets.dzone.com/posts/show/5961</link>
      <description>Contert integer to array of integer what each element is target radix.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;convRadix :: (Integral b) =&gt; b -&gt; b -&gt; [b]&lt;br /&gt;convRadix n = unfoldr (\b -&gt; if b == 0 then Nothing else Just (b `mod` n, b `div` n))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;ex.&lt;br /&gt;&gt; convRadix 10 1234&lt;br /&gt;[4, 3, 2, 1]&lt;br /&gt;&gt; convRadix 10 0&lt;br /&gt;[]&lt;br /&gt;&gt; convRadix 10 (-1)&lt;br /&gt;[9,9,...] (infinite)&lt;br /&gt;</description>
      <pubDate>Thu, 21 Aug 2008 12:11:39 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5961</guid>
      <author>mokehehe (mokehehe)</author>
    </item>
    <item>
      <title>Top Down Operator Precedence - in Haskell</title>
      <link>http://snippets.dzone.com/posts/show/5786</link>
      <description>A direct translation from &lt;a href="http://javascript.crockford.com/tdop/tdop.html"&gt;Douglas Crockford's JavaScript parser&lt;/a&gt; into Haskell keeping as close as possible to the same structure and naming.  Plus tokeniser and pretty-printer.&lt;br /&gt;&lt;br /&gt;There's also a &lt;a href="http://docs.google.com/Doc?id=dd97rbc_0gw23cmgp"&gt;side-by-side comparison&lt;/a&gt; with the original JavaScript.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module TopDownParserState where&lt;br /&gt;&lt;br /&gt;-- to stop a collision with record field id (records are kind of odd in Haskell)&lt;br /&gt;import Prelude hiding (id, error, lookup)&lt;br /&gt;import qualified Prelude&lt;br /&gt;&lt;br /&gt;-- unlike Javascript there's no inbuilt data map support&lt;br /&gt;import Data.Map (Map, (!), lookup, insert, member)&lt;br /&gt;import qualified Data.Map as Map&lt;br /&gt;&lt;br /&gt;-- support stateful function style&lt;br /&gt;import Control.Monad.State&lt;br /&gt;&lt;br /&gt;import Tokeniser&lt;br /&gt;&lt;br /&gt;type Parser a = State Env a&lt;br /&gt;&lt;br /&gt;-- Something which isn't obvious from the original variable names is&lt;br /&gt;-- that 'tokens' is input yet 'token' belongs to the completely&lt;br /&gt;-- different output type.&lt;br /&gt;data Env = Env { scope        :: Scope,&lt;br /&gt;                 symbol_table :: SymbolTable,&lt;br /&gt;                 token        :: Symbol,&lt;br /&gt;                 tokens       :: [Token] }&lt;br /&gt;&lt;br /&gt;itself = return&lt;br /&gt;&lt;br /&gt;-- This could be a simple list of scopes but I'll try to keep closely to&lt;br /&gt;-- the structure of the Javascript code&lt;br /&gt;data Scope = Scope { def    :: SymbolTable,&lt;br /&gt;                     parent :: Scope }&lt;br /&gt;           | TopScope&lt;br /&gt;&lt;br /&gt;type SymbolTable = Map Value Symbol&lt;br /&gt;&lt;br /&gt;define n@Symbol {value = value} = do&lt;br /&gt;  this &lt;- gets scope&lt;br /&gt;  let t = def this ! value&lt;br /&gt;  when (member value $ def this) $&lt;br /&gt;    error n $ if reserved t&lt;br /&gt;              then "Already reserved."&lt;br /&gt;              else "Already defined."&lt;br /&gt;  let n' = n { reserved = False,&lt;br /&gt;               nudf     = itself,&lt;br /&gt;               -- why redefine led here?&lt;br /&gt;               ledf     = \this _ -&gt; error this "Undefined operator.",&lt;br /&gt;               std      = Nothing,&lt;br /&gt;               lbp      = 0,&lt;br /&gt;               skope    = this }&lt;br /&gt;  env &lt;- get&lt;br /&gt;  put env { scope = this {&lt;br /&gt;    def = insert value n' $ def this&lt;br /&gt;  } }&lt;br /&gt;  return n'&lt;br /&gt;&lt;br /&gt;find env@Env {scope = Scope {def = def, parent = e}} n =&lt;br /&gt;  case lookup n def of&lt;br /&gt;    Just t -&gt; t&lt;br /&gt;    _      -&gt; find env { scope = e} n&lt;br /&gt;&lt;br /&gt;find Env { symbol_table = st } n =&lt;br /&gt;  case lookup n st of&lt;br /&gt;    Just t -&gt; t&lt;br /&gt;    _      -&gt; st ! "(name)"&lt;br /&gt;&lt;br /&gt;pop = do&lt;br /&gt;  env &lt;- get&lt;br /&gt;  put env { scope = parent $ scope env }&lt;br /&gt;&lt;br /&gt;reserve n@Symbol {arity = Name, reserved = False, value = value} = do&lt;br /&gt;  this &lt;- gets scope&lt;br /&gt;  let t = def this ! value&lt;br /&gt;  when (member value $ def this) $ do&lt;br /&gt;    when (reserved t) $&lt;br /&gt;      return ()&lt;br /&gt;    when (arity t == Name) $&lt;br /&gt;      error n "Unreserved is already defined."&lt;br /&gt;  env &lt;- get&lt;br /&gt;  put env { scope = this {&lt;br /&gt;    def = insert value n { reserved = True } $ def this&lt;br /&gt;  } }&lt;br /&gt;&lt;br /&gt;reserve _ = return ()&lt;br /&gt;&lt;br /&gt;new_scope = do&lt;br /&gt;  s &lt;- gets scope&lt;br /&gt;  let s' = Scope { def    = Map.empty,&lt;br /&gt;                   parent = s }&lt;br /&gt;  env &lt;- get&lt;br /&gt;  put env { scope = s' }&lt;br /&gt;  return s'&lt;br /&gt;&lt;br /&gt;advanceIf requiredId = do&lt;br /&gt;  token &lt;- gets token&lt;br /&gt;  when (id token /= requiredId) $&lt;br /&gt;    error token $ "Expected '" ++ requiredId ++ "'."&lt;br /&gt;  advance&lt;br /&gt;&lt;br /&gt;advance = do&lt;br /&gt;  this &lt;- get&lt;br /&gt;  let (t, ts) = case tokens this of&lt;br /&gt;        []&lt;br /&gt;          -&gt; (symbol_table this ! "(end)", [])&lt;br /&gt;        t@(Token a v):tokens'&lt;br /&gt;          -&gt; let (o, a') = case a of&lt;br /&gt;                   NameType&lt;br /&gt;                     -&gt; (find this $ v, Name)&lt;br /&gt;                   OperatorType&lt;br /&gt;                     -&gt; case lookup v $ symbol_table this of&lt;br /&gt;                          Just t' -&gt; (t', Operator)&lt;br /&gt;                          _       -&gt; error t "Unknown operator."&lt;br /&gt;                   NumberType&lt;br /&gt;                     -&gt; (symbol_table this ! "(literal)", Literal)&lt;br /&gt;                   StringType&lt;br /&gt;                     -&gt; (symbol_table this ! "(literal)", Literal)&lt;br /&gt;                   -- the next case can't happen and ghc throws a warning&lt;br /&gt;                   -- _         -&gt; error t "Unexpected token."&lt;br /&gt;             in (o { value = v, arity = a' }, tokens')&lt;br /&gt;&lt;br /&gt;  put this { token = t, tokens = ts }&lt;br /&gt;  return t&lt;br /&gt;&lt;br /&gt;expression rbp = do&lt;br /&gt;  t &lt;- gets token&lt;br /&gt;  advance&lt;br /&gt;  left &lt;- nud t&lt;br /&gt;  let walkRight left = do&lt;br /&gt;        t &lt;- gets token&lt;br /&gt;        if rbp &lt; lbp t then do&lt;br /&gt;            advance&lt;br /&gt;            left &lt;- led t left&lt;br /&gt;            walkRight left&lt;br /&gt;          else return left&lt;br /&gt;  walkRight left&lt;br /&gt;&lt;br /&gt;type NudFun = This -&gt; Parser Symbol&lt;br /&gt;type LedFun = This -&gt; Symbol -&gt; Parser Symbol&lt;br /&gt;&lt;br /&gt;statement = do&lt;br /&gt;  n &lt;- gets token&lt;br /&gt;  case n of&lt;br /&gt;    Symbol { std = Just std } -&gt; do&lt;br /&gt;      advance&lt;br /&gt;      reserve n&lt;br /&gt;      std n&lt;br /&gt;    otherwise -&gt; do&lt;br /&gt;      v &lt;- expression 0&lt;br /&gt;      when (not (isAssignment v) &amp;&amp; id v /= "(") $&lt;br /&gt;        error v "Bad expression statement."&lt;br /&gt;      advanceIf ";"&lt;br /&gt;      return [v]&lt;br /&gt;&lt;br /&gt;type StdFun = This -&gt; Parser [Symbol]&lt;br /&gt;&lt;br /&gt;-- For this function and all like it we don't change the return type&lt;br /&gt;-- but instead make the pretty printer treat empty lists as null and&lt;br /&gt;-- single element lists as the element.  To simplify the structure&lt;br /&gt;-- of the Symbol data structure we also apply the equivilent&lt;br /&gt;-- transformation there which means that single element lists appear&lt;br /&gt;-- in many places where the Javascript uses just the element.&lt;br /&gt;-- Because we apply this transformation uniformly there are cases&lt;br /&gt;-- where our output is slightly different from the original.&lt;br /&gt;statements = do&lt;br /&gt;  token &lt;- gets token&lt;br /&gt;  if id token == "}" || id token == "(end)"&lt;br /&gt;    then return []&lt;br /&gt;    else do&lt;br /&gt;      s &lt;- statement&lt;br /&gt;      ss &lt;- statements&lt;br /&gt;      return $ s ++ ss&lt;br /&gt;&lt;br /&gt;block = do&lt;br /&gt;  t &lt;- gets token&lt;br /&gt;  advanceIf "{"&lt;br /&gt;  case std t of&lt;br /&gt;    Just s -&gt; s t&lt;br /&gt;&lt;br /&gt;data Symbol = Symbol { id    :: Id,&lt;br /&gt;                       arity :: Arity,&lt;br /&gt;                       value :: Value,&lt;br /&gt;                       lbp   :: BindingPower,&lt;br /&gt;                       reserved, isAssignment :: Bool,&lt;br /&gt;                       nudf  :: NudFun,&lt;br /&gt;                       ledf  :: LedFun,&lt;br /&gt;                       std   :: Maybe StdFun,&lt;br /&gt;                       skope :: Scope,&lt;br /&gt;                       key   :: Maybe Value,&lt;br /&gt;                       first, second, third :: [Symbol] }&lt;br /&gt;&lt;br /&gt;data Arity = Name | Operator | Literal | Unary | Binary | Ternary&lt;br /&gt;           | Statement | This&lt;br /&gt;           | Function { name :: Maybe Value }&lt;br /&gt;           deriving (Eq, Show)&lt;br /&gt;&lt;br /&gt;original_symbol = Symbol {&lt;br /&gt;  nudf = \this   -&gt; error this "Undefined.",&lt;br /&gt;  ledf = \this _ -&gt; error this "Missing operator.",&lt;br /&gt;  std  = Nothing,&lt;br /&gt;  first = [], second = [], third = [],&lt;br /&gt;  id = undefined, arity = undefined, value = undefined, lbp = undefined,&lt;br /&gt;  isAssignment = False, skope = undefined, reserved = False,&lt;br /&gt;  key = Nothing&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;-- helper functions to access nudf/ledf with correct "object"&lt;br /&gt;nud s = nudf s s&lt;br /&gt;led s = ledf s s&lt;br /&gt;&lt;br /&gt;symbol0 id = symbol1 id NilT&lt;br /&gt;symbol1    = flip symbol 0&lt;br /&gt;&lt;br /&gt;-- rather than make Symbol mutable this binds the function during&lt;br /&gt;-- the symbol creation&lt;br /&gt;-- symbol :: Id -&gt; BindingPower -&gt; SymbolType -&gt; State SymbolTable Symbol&lt;br /&gt;symbol id bp typ = do&lt;br /&gt;  st &lt;- get&lt;br /&gt;  let s' = bind typ $&lt;br /&gt;           case lookup id st of&lt;br /&gt;             Just s -&gt; if bp &gt;= lbp s&lt;br /&gt;                       then s { lbp = bp }&lt;br /&gt;                       else s&lt;br /&gt;             _ -&gt; original_symbol { id    = id,&lt;br /&gt;                                    value = id,&lt;br /&gt;                                    lbp   = bp }&lt;br /&gt;  put $ insert id s' st&lt;br /&gt;  return s'&lt;br /&gt;    where&lt;br /&gt;      bind (Nud f) s = s { nudf = f }&lt;br /&gt;      bind (Led f) s = s { ledf = f }&lt;br /&gt;      bind (Std f) s = s { std  = Just f }&lt;br /&gt;      bind _       s = s&lt;br /&gt;&lt;br /&gt;data SymbolType = NilT &lt;br /&gt;                | Nud NudFun&lt;br /&gt;                | Led LedFun&lt;br /&gt;                | Std StdFun&lt;br /&gt;&lt;br /&gt;-- this constant doesn't use the value because that would require a&lt;br /&gt;-- datatype for all the kinds of javascript types it could be set to&lt;br /&gt;constant0 s v = constant s v $ \this -&gt; do&lt;br /&gt;  reserve this&lt;br /&gt;  symbol_table &lt;- gets symbol_table&lt;br /&gt;  return this { value = value $ symbol_table ! id this,&lt;br /&gt;                arity = Literal }&lt;br /&gt;&lt;br /&gt;constant s _ f = symbol1 s $ Nud f&lt;br /&gt;&lt;br /&gt;-- infix is a keyword&lt;br /&gt;inphix0 s bp = inphix s bp $ \this left -&gt; do&lt;br /&gt;  right &lt;- expression bp&lt;br /&gt;  return this { first  = [left],&lt;br /&gt;                second = [right],&lt;br /&gt;                arity  = Binary }&lt;br /&gt;&lt;br /&gt;inphix s bp f = symbol s bp $ Led f&lt;br /&gt;&lt;br /&gt;inphixr0 s bp = inphixr s bp $ \this left -&gt; do&lt;br /&gt;  right &lt;- expression $ bp-1&lt;br /&gt;  return this { first  = [left],&lt;br /&gt;                second = [right],&lt;br /&gt;                arity  = Binary }&lt;br /&gt;&lt;br /&gt;-- infixr is a keyword&lt;br /&gt;inphixr = inphix&lt;br /&gt;&lt;br /&gt;assignment s = inphixr s 10 $ \this left -&gt; do&lt;br /&gt;  when (id left /= "." &amp;&amp; id left /= "[" &amp;&amp; arity left /= Name) $&lt;br /&gt;    error left "Bad lvalue."&lt;br /&gt;  right &lt;- expression 9&lt;br /&gt;  return this { first  = [left],&lt;br /&gt;                second = [right],&lt;br /&gt;                arity  = Binary,&lt;br /&gt;                isAssignment = True }&lt;br /&gt;&lt;br /&gt;-- prefix isn't a keyword but to named to match inphix and inphixr&lt;br /&gt;prephix0 s = prephix s $ \this -&gt; do&lt;br /&gt;  reserve this&lt;br /&gt;  expr &lt;- expression 70&lt;br /&gt;  return this { first = [expr],&lt;br /&gt;                arity = Unary }&lt;br /&gt;&lt;br /&gt;prephix s f = symbol1 s $ Nud f&lt;br /&gt;&lt;br /&gt;stmt s f = symbol1 s $ Std f&lt;br /&gt;&lt;br /&gt;initial_symbol_table = execState ist Map.empty&lt;br /&gt;    where &lt;br /&gt;      ist = do&lt;br /&gt;&lt;br /&gt;      symbol0 "(end)"&lt;br /&gt;      symbol0 "(name)"&lt;br /&gt;&lt;br /&gt;      symbol0 ":"&lt;br /&gt;      symbol0 ";"&lt;br /&gt;      symbol0 ")"&lt;br /&gt;      symbol0 "]"&lt;br /&gt;      symbol0 "}"&lt;br /&gt;      symbol0 ","&lt;br /&gt;      symbol0 "else"&lt;br /&gt;&lt;br /&gt;      constant0 "true" True&lt;br /&gt;      constant0 "false" False&lt;br /&gt;      constant0 "null" undefined&lt;br /&gt;      constant0 "pi" 3.141592653589793&lt;br /&gt;      constant0 "Object" Map.empty&lt;br /&gt;      constant0 "Array" []&lt;br /&gt;&lt;br /&gt;      symbol1 "(literal)" $ Nud itself&lt;br /&gt;&lt;br /&gt;      symbol1 "this" $ Nud $ \this -&gt; do&lt;br /&gt;        reserve this&lt;br /&gt;        return this { arity = This }&lt;br /&gt;&lt;br /&gt;      assignment "="&lt;br /&gt;      assignment "+="&lt;br /&gt;      assignment "-="&lt;br /&gt;&lt;br /&gt;      inphix "?" 20 $ \this left -&gt; do&lt;br /&gt;        whenTrue &lt;- expression 0&lt;br /&gt;        advanceIf ":"&lt;br /&gt;        whenFalse &lt;- expression 0&lt;br /&gt;        return this { first  = [left],&lt;br /&gt;                      second = [whenTrue],&lt;br /&gt;                      third  = [whenFalse],&lt;br /&gt;                      arity  = Ternary }&lt;br /&gt;&lt;br /&gt;      inphixr0 "&amp;&amp;" 30&lt;br /&gt;      inphixr0 "||" 30&lt;br /&gt;&lt;br /&gt;      inphixr0 "===" 40&lt;br /&gt;      inphixr0 "!==" 40&lt;br /&gt;      inphixr0 "&lt;" 40&lt;br /&gt;      inphixr0 "&lt;=" 40&lt;br /&gt;      inphixr0 "&gt;" 40&lt;br /&gt;      inphixr0 "&gt;=" 40&lt;br /&gt;&lt;br /&gt;      inphix0 "+" 50&lt;br /&gt;      inphix0 "-" 50&lt;br /&gt;&lt;br /&gt;      inphix0 "*" 60&lt;br /&gt;      inphix0 "/" 60&lt;br /&gt;&lt;br /&gt;      inphix "." 80 $ \this left -&gt; do&lt;br /&gt;        token &lt;- gets token&lt;br /&gt;        when (arity token /= Name) $&lt;br /&gt;          error token "Expected a property name."&lt;br /&gt;        -- Even though the Javascript updates the token it is then&lt;br /&gt;        -- immediately discaded by 'advance' so we won't bother&lt;br /&gt;        advance&lt;br /&gt;        return this { first  = [left],&lt;br /&gt;                      second = [token { arity = Literal }],&lt;br /&gt;                      arity  = Binary }&lt;br /&gt;&lt;br /&gt;      inphix "[" 80 $ \this left -&gt; do&lt;br /&gt;        s &lt;- expression 0&lt;br /&gt;        advanceIf "]"&lt;br /&gt;        return this { first  = [left],&lt;br /&gt;                      second = [s],&lt;br /&gt;                      arity  = Binary }&lt;br /&gt;&lt;br /&gt;      inphix "(" 80 $ \this left -&gt; do&lt;br /&gt;        t &lt;- gets token&lt;br /&gt;        a &lt;- if id t /= ")" then&lt;br /&gt;               let vars = do&lt;br /&gt;                     e &lt;- expression 0&lt;br /&gt;                     token &lt;- gets token&lt;br /&gt;                     if id token /= ","&lt;br /&gt;                       then return [e]&lt;br /&gt;                       else do&lt;br /&gt;                         advanceIf ","&lt;br /&gt;                         v &lt;- vars&lt;br /&gt;                         return $ e:v&lt;br /&gt;               in vars&lt;br /&gt;             else return []&lt;br /&gt;        -- can't use a before it's been populated&lt;br /&gt;        let this' = if id left == "." || id left == "["&lt;br /&gt;                    then this { first  = first left,&lt;br /&gt;                                second = second left,&lt;br /&gt;                                third  = a,&lt;br /&gt;                                arity  = Ternary }&lt;br /&gt;                    else if (arity left /= Unary || id left /= "function") &amp;&amp;&lt;br /&gt;                            arity left /= Name &amp;&amp; id left /= "(" &amp;&amp;&lt;br /&gt;                            id left /= "&amp;&amp;" &amp;&amp; id left /= "||" &amp;&amp; id left /= "?"&lt;br /&gt;                         then error left "Expected a variable name."&lt;br /&gt;                         else this { first  = [left],&lt;br /&gt;                                     second = a,&lt;br /&gt;                                     arity  = Binary }&lt;br /&gt;        advanceIf ")"&lt;br /&gt;        return this'&lt;br /&gt;&lt;br /&gt;      prephix0 "!"&lt;br /&gt;      prephix0 "-"&lt;br /&gt;      prephix0 "typeof"&lt;br /&gt;&lt;br /&gt;      prephix "(" $ \this -&gt; do&lt;br /&gt;        e &lt;- expression 0&lt;br /&gt;        advanceIf ")"&lt;br /&gt;        return e&lt;br /&gt;&lt;br /&gt;      prephix "function" $ \this -&gt; do&lt;br /&gt;        new_scope&lt;br /&gt;        t &lt;- gets token&lt;br /&gt;        n &lt;- if arity t == Name then do&lt;br /&gt;               define t&lt;br /&gt;               advance&lt;br /&gt;               return $ Just $ value t&lt;br /&gt;             else return Nothing&lt;br /&gt;        t &lt;- advanceIf "("&lt;br /&gt;        a &lt;- if id t /= ")" then&lt;br /&gt;               let params = do&lt;br /&gt;                     t &lt;- gets token&lt;br /&gt;                     when (arity t /= Name) $&lt;br /&gt;                       error t "Expected a parameter name."&lt;br /&gt;                     define t&lt;br /&gt;                     token &lt;- advance&lt;br /&gt;                     if id token /= ","&lt;br /&gt;                       then return [t]&lt;br /&gt;                       else do&lt;br /&gt;                         advanceIf ","&lt;br /&gt;                         p &lt;- params&lt;br /&gt;                         return $ t:p&lt;br /&gt;               in params&lt;br /&gt;             else return []&lt;br /&gt;        advanceIf ")"&lt;br /&gt;        advanceIf "{"&lt;br /&gt;        s &lt;- statements&lt;br /&gt;        advanceIf "}"&lt;br /&gt;        pop&lt;br /&gt;        return this { first  = a,&lt;br /&gt;                      second = s,&lt;br /&gt;                      arity  = Function { name = n } }&lt;br /&gt;&lt;br /&gt;      prephix "[" $ \this -&gt; do&lt;br /&gt;        t &lt;- gets token&lt;br /&gt;        a &lt;- if id t /= "]" then&lt;br /&gt;               let entries = do&lt;br /&gt;                     v &lt;- expression 0&lt;br /&gt;                     token &lt;- gets token&lt;br /&gt;                     if id token /= ","&lt;br /&gt;                       then return [v]&lt;br /&gt;                       else do&lt;br /&gt;                         advanceIf ","&lt;br /&gt;                         e &lt;- entries&lt;br /&gt;                         return $ v:e&lt;br /&gt;               in entries&lt;br /&gt;             else return []&lt;br /&gt;        advanceIf "]"&lt;br /&gt;        return this { first = a,&lt;br /&gt;                      arity = Unary }&lt;br /&gt;&lt;br /&gt;      prephix "{" $ \this -&gt; do&lt;br /&gt;        t &lt;- gets token&lt;br /&gt;        a &lt;- if id t /= "}" then&lt;br /&gt;               let entries = do&lt;br /&gt;                     n &lt;- gets token&lt;br /&gt;                     when (arity n /= Name &amp;&amp; arity n /= Literal) $&lt;br /&gt;                       error n "Bad property name."&lt;br /&gt;                     advance&lt;br /&gt;                     advanceIf ":"&lt;br /&gt;                     v &lt;- expression 0&lt;br /&gt;                     let v' = v { key = Just $ value n }&lt;br /&gt;                     token &lt;- gets token&lt;br /&gt;                     if id token /= ","&lt;br /&gt;                       then return [v']&lt;br /&gt;                       else do&lt;br /&gt;                         advanceIf ","&lt;br /&gt;                         e &lt;- entries&lt;br /&gt;                         return $ v':e&lt;br /&gt;               in entries&lt;br /&gt;             else return []&lt;br /&gt;        advanceIf "}"&lt;br /&gt;        return this { first = a, &lt;br /&gt;                      arity = Unary }&lt;br /&gt;&lt;br /&gt;      stmt "{" $ \this -&gt; do&lt;br /&gt;        new_scope&lt;br /&gt;        a &lt;- statements&lt;br /&gt;        advanceIf "}"&lt;br /&gt;        pop&lt;br /&gt;        return a&lt;br /&gt;&lt;br /&gt;      stmt "var" $ \this -&gt; do&lt;br /&gt;        let vars = do&lt;br /&gt;              n &lt;- gets token&lt;br /&gt;              when (arity n /= Name) $&lt;br /&gt;                error n "Expected a new variable name."&lt;br /&gt;              define n&lt;br /&gt;              t &lt;- advance&lt;br /&gt;              a &lt;- if id t == "=" then do&lt;br /&gt;                     advanceIf "="&lt;br /&gt;                     s &lt;- expression 0&lt;br /&gt;                     let t' = t { first  = [n],&lt;br /&gt;                                  second = [s],&lt;br /&gt;                                  arity  = Binary,&lt;br /&gt;                                  isAssignment = True }&lt;br /&gt;                     return [t']&lt;br /&gt;                   else return []&lt;br /&gt;              t &lt;- gets token&lt;br /&gt;              if id t /= ","&lt;br /&gt;                then return a&lt;br /&gt;                else do&lt;br /&gt;                  advanceIf ","&lt;br /&gt;                  v &lt;- vars&lt;br /&gt;                  return $ a++v&lt;br /&gt;&lt;br /&gt;        a &lt;- vars&lt;br /&gt;        advanceIf ";"&lt;br /&gt;        return a&lt;br /&gt;&lt;br /&gt;      stmt "if" $ \this -&gt; do&lt;br /&gt;        advanceIf "("&lt;br /&gt;        test &lt;- expression 0&lt;br /&gt;        advanceIf ")"&lt;br /&gt;        body &lt;- block&lt;br /&gt;        token &lt;- gets token&lt;br /&gt;        els &lt;- if id token == "else" then do&lt;br /&gt;                 reserve token&lt;br /&gt;                 token &lt;- advanceIf "else"&lt;br /&gt;                 if id token == "if" then statement else block&lt;br /&gt;               else return []&lt;br /&gt;        return [this { first  = [test],&lt;br /&gt;                       second = body,&lt;br /&gt;                       third  = els,&lt;br /&gt;                       arity  = Statement }]&lt;br /&gt;&lt;br /&gt;      stmt "return" $ \this -&gt; do&lt;br /&gt;        t &lt;- gets token&lt;br /&gt;        first &lt;- if id t /= ";" then do&lt;br /&gt;                   e &lt;- expression 0&lt;br /&gt;                   return [e]&lt;br /&gt;                 else return []&lt;br /&gt;        t &lt;- advanceIf ";"&lt;br /&gt;        when (id t /= "}") $&lt;br /&gt;          error t "Unreachable statement."&lt;br /&gt;        return [this { first = first,&lt;br /&gt;                       arity = Statement }]&lt;br /&gt;&lt;br /&gt;      stmt "break" $ \this -&gt; do&lt;br /&gt;        t &lt;- advanceIf ";"&lt;br /&gt;        when (id t /= "}") $&lt;br /&gt;          error t "Unreachable statement."&lt;br /&gt;        return [this { arity = Statement }]&lt;br /&gt;&lt;br /&gt;      stmt "while" $ \this -&gt; do&lt;br /&gt;        advanceIf "("&lt;br /&gt;        f &lt;- expression 0&lt;br /&gt;        advanceIf ")"&lt;br /&gt;        s &lt;- block&lt;br /&gt;        return [this { first  = [f],&lt;br /&gt;                       second = s,&lt;br /&gt;                       arity  = Statement }]&lt;br /&gt;&lt;br /&gt;parse source = &lt;br /&gt;  evalState ( do&lt;br /&gt;    new_scope&lt;br /&gt;    advance&lt;br /&gt;    s &lt;- statements&lt;br /&gt;    advanceIf "(end)"&lt;br /&gt;    return s&lt;br /&gt;  ) Env { tokens       = tokenise source,&lt;br /&gt;          scope        = TopScope,&lt;br /&gt;          token        = original_symbol { id = "(start)" },&lt;br /&gt;          symbol_table = initial_symbol_table }&lt;br /&gt;&lt;br /&gt;type Value        = String&lt;br /&gt;type Id           = String&lt;br /&gt;type BindingPower = Int&lt;br /&gt;type This         = Symbol&lt;br /&gt;&lt;br /&gt;error t msg = Prelude.error $ msg ++ " " ++ show t&lt;br /&gt;&lt;br /&gt;instance Show Symbol where&lt;br /&gt;    show Symbol { value = value, arity = arity } =&lt;br /&gt;      "{value: " ++ show value ++ " " ++ show arity ++ "}"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module Tokeniser where&lt;br /&gt;&lt;br /&gt;import Text.Read (lex)&lt;br /&gt;import Data.Char (isAlpha, isNumber)&lt;br /&gt;&lt;br /&gt;data Token     = Token TokenType String&lt;br /&gt;                 deriving Show&lt;br /&gt;data TokenType = NameType | StringType | NumberType | OperatorType&lt;br /&gt;                 deriving Show&lt;br /&gt;&lt;br /&gt;tokenise = tokens . head . lex&lt;br /&gt;    where&lt;br /&gt;      tokens (t, "") = [token t]&lt;br /&gt;      tokens (t, s)  =  token t : tokenise s&lt;br /&gt;&lt;br /&gt;      token t@(c:_) = Token tokenType text&lt;br /&gt;          where&lt;br /&gt;            tokenType | isAlpha  c = NameType     &lt;br /&gt;                      | isNumber c = NumberType   &lt;br /&gt;                      | '"' ==   c = StringType&lt;br /&gt;                      | otherwise  = OperatorType &lt;br /&gt;&lt;br /&gt;            text | c == '"'  = drop 1 $ take (length t-1) t&lt;br /&gt;                 | otherwise = t&lt;br /&gt;&lt;br /&gt;      token _ = Token OperatorType "(end)"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module PrettyPrint where&lt;br /&gt;&lt;br /&gt;import Text.PrettyPrint&lt;br /&gt;&lt;br /&gt;import TopDownParserState&lt;br /&gt;&lt;br /&gt;pp = ppList ""&lt;br /&gt;&lt;br /&gt;ppList l []     = empty&lt;br /&gt;ppList l (s:[]) = ppSymbol l s&lt;br /&gt;ppList l s      = bracket l $&lt;br /&gt;                    vcat $ map (ppSymbol "") s&lt;br /&gt;&lt;br /&gt;ppSymbol l Symbol {key = k, value = v, arity = a,&lt;br /&gt;                   first = f, second = s, third = t } =&lt;br /&gt;    brace l $&lt;br /&gt;      ppMaybe "key: " k $$&lt;br /&gt;      ppValue v $$&lt;br /&gt;      ppArity a $$&lt;br /&gt;      ppList "first: " f $$&lt;br /&gt;      ppList "second: " s $$&lt;br /&gt;      ppList "third: " t&lt;br /&gt;&lt;br /&gt;ppMaybe l (Just k) = text l &lt;&gt; textOf k&lt;br /&gt;ppMaybe l Nothing  = empty&lt;br /&gt;&lt;br /&gt;ppValue v = text "value: " &lt;&gt; textOf v&lt;br /&gt;&lt;br /&gt;ppArity a@Function {name = n} =&lt;br /&gt;    text "arity: Function" $$&lt;br /&gt;    ppMaybe "name: " n&lt;br /&gt;ppArity a = text "arity: " &lt;&gt; textOf a&lt;br /&gt;&lt;br /&gt;textOf :: Show a =&gt; a -&gt; Doc&lt;br /&gt;textOf = text . show&lt;br /&gt;&lt;br /&gt;bracket l s = (text l &lt;&gt; lbrack) $+$ indent s $$ rbrack&lt;br /&gt;brace   l s = (text l &lt;&gt; lbrace) $+$ indent s $$ rbrace&lt;br /&gt;&lt;br /&gt;indent = nest 4&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;</description>
      <pubDate>Fri, 18 Jul 2008 03:42:39 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5786</guid>
      <author>Rohan (Rohan Hart)</author>
    </item>
    <item>
      <title>Haskell Regular Expression Matcher</title>
      <link>http://snippets.dzone.com/posts/show/4434</link>
      <description>Basic implementation of Regular Expressions based on "Derivatives of Regular Expressions" by Janusz A. Brzozowski (Journal of Association for Computing Machinery, October 1964)&lt;br /&gt;&lt;br /&gt;Not really intended for serious use. Just a proof of concept.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module Regexp&lt;br /&gt;where&lt;br /&gt;&lt;br /&gt;import Data.Set (Set)&lt;br /&gt;import Data.Map (Map)&lt;br /&gt;import Monad&lt;br /&gt;import List&lt;br /&gt;import Maybe&lt;br /&gt;import qualified Data.Set as Set&lt;br /&gt;import qualified Data.Map as Map&lt;br /&gt;&lt;br /&gt;data Regexp = &lt;br /&gt;    Zero&lt;br /&gt;  | Match Char       -- matches a single char&lt;br /&gt;  | Not Regexp       -- matches the negation of its argument&lt;br /&gt;  | Prod [Regexp]    -- matches a concatentation of its arguments&lt;br /&gt;  | Sum (Set Regexp) -- matches either of its arguments&lt;br /&gt;  | Star Regexp      -- matches repetitions of its argument (including 0 repetitions)&lt;br /&gt;  deriving (Eq, Ord)&lt;br /&gt;&lt;br /&gt;instance Show Regexp where&lt;br /&gt;  show Zero = "0"&lt;br /&gt;  show (Match c) = [c]&lt;br /&gt;  show (Not x)   = '~' : show x&lt;br /&gt;  show (Prod x) = join . (map show)  $ x&lt;br /&gt;  show (Sum x) = "(" ++ ( join . intersperse "|" . (map show) . Set.toList $ x ) ++ ")"&lt;br /&gt;  show (Star x) = "(" ++ show x ++ ")*" &lt;br /&gt;&lt;br /&gt;-- Flagrant abuse of type classes to allow implicit conversion of datatypes into regular&lt;br /&gt;-- expressions.&lt;br /&gt;class Match a where&lt;br /&gt;  match :: a -&gt; Regexp&lt;br /&gt;&lt;br /&gt;instance Match Char where&lt;br /&gt;  match c = Match c&lt;br /&gt;&lt;br /&gt;instance (Match a) =&gt; Match [a] where&lt;br /&gt;  match = con&lt;br /&gt;&lt;br /&gt;instance Match Regexp where&lt;br /&gt;  match = id&lt;br /&gt;&lt;br /&gt;-- "smart" versions of the constructors, which perform normalisation of the datatype.&lt;br /&gt;-- As long as all regular expressions are built up using these and the match instance&lt;br /&gt;-- for char we can guarantee that structural equality of terms == similarity.&lt;br /&gt;-- This is important to make sure we only generate a finite number of states.&lt;br /&gt;zero :: Regexp &lt;br /&gt;zero = Zero &lt;br /&gt;&lt;br /&gt;one :: Regexp&lt;br /&gt;one = Prod []&lt;br /&gt;&lt;br /&gt;(&lt;+&gt;) :: (Match a, Match b) =&gt; a -&gt; b -&gt; Regexp&lt;br /&gt;x &lt;+&gt; y = &lt;br /&gt;  case (match x, match y) of&lt;br /&gt;    (Zero, b)      -&gt; b&lt;br /&gt;    (a, Zero)      -&gt; a&lt;br /&gt;    (Sum a, Sum b) -&gt; Sum (Set.union a b)&lt;br /&gt;    (Sum a, b)     -&gt; Sum (Set.insert b a)&lt;br /&gt;    (a, Sum b)     -&gt; Sum (Set.insert a b)    &lt;br /&gt;    (a, b)         -&gt; Sum $ Set.fromList [a, b]&lt;br /&gt;  &lt;br /&gt;oneOf :: (Match a) =&gt; [a] -&gt; Regexp&lt;br /&gt;oneOf = foldr (&lt;+&gt;) zero&lt;br /&gt;&lt;br /&gt;(&lt;*&gt;) :: (Match a, Match b) =&gt; a -&gt; b -&gt; Regexp&lt;br /&gt;u &lt;*&gt; v = &lt;br /&gt;  case (match u, match v) of &lt;br /&gt;    (Zero, _)         -&gt; zero&lt;br /&gt;    (_, Zero)         -&gt; zero&lt;br /&gt;    (Prod x, Prod y)  -&gt; Prod (x ++ y)&lt;br /&gt;    (Prod x, y)       -&gt; Prod (x ++ [y])&lt;br /&gt;    (x, Prod y)       -&gt; Prod (x : y)&lt;br /&gt;    (x, y)            -&gt; Prod [x, y]&lt;br /&gt;&lt;br /&gt;con :: (Match a) =&gt; [a] -&gt; Regexp&lt;br /&gt;con = foldr (&lt;*&gt;) one&lt;br /&gt;&lt;br /&gt;neg :: (Match a) =&gt; a -&gt; Regexp&lt;br /&gt;neg x = &lt;br /&gt;  case (match x) of&lt;br /&gt;  (Not y) -&gt; y&lt;br /&gt;  y       -&gt; Not y&lt;br /&gt;&lt;br /&gt;star :: (Match a) =&gt; a -&gt; Regexp&lt;br /&gt;star x =&lt;br /&gt;  case (match x) of&lt;br /&gt;    (Zero)   -&gt; Zero&lt;br /&gt;    (Star y) -&gt; Star y&lt;br /&gt;    y        -&gt; Star y&lt;br /&gt;&lt;br /&gt;-- Returns if the regex matches the empty string.&lt;br /&gt;del :: Regexp -&gt; Bool&lt;br /&gt;del (Zero)    = False&lt;br /&gt;del (Sum x)   = or . map del $ Set.toList x&lt;br /&gt;del (Prod x)  = and . map del $ x&lt;br /&gt;del (Match _) = False&lt;br /&gt;del (Not x)   = not $ del x;&lt;br /&gt;del (Star _)  = True&lt;br /&gt;&lt;br /&gt;-- The derivative of a regular language A with respect to a character&lt;br /&gt;-- c is dA/dc = { s : cs \in A } &lt;br /&gt;diff :: Char -&gt; Regexp -&gt; Regexp&lt;br /&gt;diff _ (Zero)  = zero&lt;br /&gt;diff c (Match d) | (c == d) = one&lt;br /&gt;diff c (Match d) = zero&lt;br /&gt;diff c (Sum x) = oneOf $ (map $ diff c) (Set.toList x)&lt;br /&gt;diff c (Prod []) = zero&lt;br /&gt;diff c (Prod (x:xs)) | del x = (diff c x &lt;*&gt; xs) &lt;+&gt; diff c (Prod xs)&lt;br /&gt;diff c (Prod (x:xs)) = diff c x &lt;*&gt; xs&lt;br /&gt;diff c (Not x) = Not (diff c x)&lt;br /&gt;diff c (Star x) = diff c x &lt;*&gt; Star x&lt;br /&gt;&lt;br /&gt;flattenSet :: (Ord a) =&gt; Set (Set a) -&gt; Set a&lt;br /&gt;flattenSet = Set.fold Set.union Set.empty&lt;br /&gt;&lt;br /&gt;(/&gt;&gt;=) :: (Ord a, Ord b) =&gt; Set a -&gt; (a -&gt; Set b) -&gt; Set b&lt;br /&gt;x /&gt;&gt;= f = flattenSet (Set.map f x)&lt;br /&gt;&lt;br /&gt;-- The alphabet of all characters that appear in this regexp&lt;br /&gt;alphabet :: Regexp -&gt; Set Char&lt;br /&gt;alphabet (Zero) = Set.empty&lt;br /&gt;alphabet (Sum x) = flattenSet (Set.map alphabet x) &lt;br /&gt;alphabet (Prod x) = Set.unions $ map alphabet x&lt;br /&gt;alphabet (Not x) = alphabet x&lt;br /&gt;alphabet (Star x) = alphabet x&lt;br /&gt;alphabet (Match c) = Set.singleton c&lt;br /&gt;&lt;br /&gt;-- Set of all derivatives of a regular expression (including itself, and higher order derivatives).&lt;br /&gt;derivatives :: Regexp -&gt; [Regexp]&lt;br /&gt;derivatives exp = Set.toList $ enlarge (Set.singleton exp) (Set.singleton exp) &lt;br /&gt;  where&lt;br /&gt;    alpha = alphabet exp&lt;br /&gt;    firstDerivatives x = Set.map (`diff` x) alpha &lt;br /&gt;    enlarge :: Set Regexp -&gt; Set Regexp -&gt; Set Regexp&lt;br /&gt;    enlarge new found = &lt;br /&gt;      if Set.null new&lt;br /&gt;        then found&lt;br /&gt;        else&lt;br /&gt;          let nextNew   = (new /&gt;&gt;= firstDerivatives) Set.\\ found&lt;br /&gt;              nextFound = found `Set.union` nextNew&lt;br /&gt;          in enlarge nextNew nextFound&lt;br /&gt;&lt;br /&gt;-- A simple finite state machine type &lt;br /&gt;data FSM = State { transitions :: (Map Char FSM), isFinal :: Bool } &lt;br /&gt;&lt;br /&gt;-- Converts a Regexp into a finite state machine by using the derivatives&lt;br /&gt;-- with respect to specific characters as the transitions. Essentially at &lt;br /&gt;-- each stage we build up a regular expression that the remaining characters&lt;br /&gt;-- have to match. Due to Cunning Mathematics, only finitely many such regular&lt;br /&gt;-- expressions (up to similarity) result.&lt;br /&gt;compile :: Regexp -&gt; FSM&lt;br /&gt;compile x = fromJust $ Map.lookup x states&lt;br /&gt;  where&lt;br /&gt;    states :: Map Regexp FSM&lt;br /&gt;    states = Map.fromList $&lt;br /&gt;      do re &lt;- derivatives x -- Totally gratuitious use of list monad. :)&lt;br /&gt;         let trans = do c &lt;- Set.toList $ alphabet re&lt;br /&gt;                        let d = diff c re&lt;br /&gt;                        return (c, fromJust $ Map.lookup d states)&lt;br /&gt;         let state = State (Map.fromList trans) (del re) &lt;br /&gt;         return (re, state) &lt;br /&gt;&lt;br /&gt;runFSM :: FSM -&gt; String -&gt; Bool&lt;br /&gt;runFSM x []     = isFinal x&lt;br /&gt;runFSM x (c:cs) = case (Map.lookup c $ transitions x) of&lt;br /&gt;                    Nothing -&gt; False&lt;br /&gt;                    Just y  -&gt; runFSM y cs&lt;br /&gt;               &lt;br /&gt;matches :: (Match a) =&gt; String -&gt; a -&gt; Bool&lt;br /&gt;matches cs exp = runFSM (compile $  match exp) cs&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 19 Aug 2007 20:57:56 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4434</guid>
      <author>DRMacIver (David R. MacIver)</author>
    </item>
    <item>
      <title>Simple Haskell script for word counting</title>
      <link>http://snippets.dzone.com/posts/show/4263</link>
      <description>This is just a simple piece of code I put together to play with some Haskell when I realised I've not been writing nearly enough of the stuff. &lt;br /&gt;&lt;br /&gt;It reads text from stdin and prints the words it finds together with how many times each one occurred.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module Main&lt;br /&gt;where&lt;br /&gt;&lt;br /&gt;import List&lt;br /&gt;import Control.Arrow&lt;br /&gt;&lt;br /&gt;type Comparator a = (a -&gt; a -&gt; Ordering)&lt;br /&gt;&lt;br /&gt;ascending :: (Ord a) =&gt; (b -&gt; a) -&gt; Comparator b&lt;br /&gt;ascending f x y = compare (f x) (f y)&lt;br /&gt;&lt;br /&gt;descending :: (Ord a) =&gt; (b -&gt; a) -&gt; Comparator b&lt;br /&gt;descending = flip . ascending&lt;br /&gt;&lt;br /&gt;secondary :: Comparator a -&gt; Comparator a -&gt; Comparator a&lt;br /&gt;secondary f g x y = case f x y of {&lt;br /&gt;                    EQ -&gt; g x y;&lt;br /&gt;                    z  -&gt; z; }&lt;br /&gt;&lt;br /&gt;-- Returns a list of unique elements together with their frequency. Listed in decreasing order of frequency, followed by&lt;br /&gt;increasing order of the elements.&lt;br /&gt;count :: (Ord a) =&gt; [a] -&gt; [(a, Int)]&lt;br /&gt;count = map (head &amp;&amp;&amp; length) . sortBy (descending length `secondary` ascending head) . group . sort&lt;br /&gt;&lt;br /&gt;main :: IO ()&lt;br /&gt;main = interact $ unlines . map (\(x, y) -&gt; (take 20 $ x ++ repeat ' ')  ++ " : " ++ show y) . count . words&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 05 Jul 2007 13:52:45 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4263</guid>
      <author>DRMacIver (David R. MacIver)</author>
    </item>
    <item>
      <title>Putlines in Haskell</title>
      <link>http://snippets.dzone.com/posts/show/3997</link>
      <description>This is an illustrative example of &lt;br /&gt;&lt;br /&gt;a) Point free style&lt;br /&gt;b) How Haskell IO works.&lt;br /&gt;&lt;br /&gt;If you don't understand Haskell IO, it might be helpful to try and unpick the definition here to see how it works. :-)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import System&lt;br /&gt;&lt;br /&gt;main :: IO ()&lt;br /&gt;main = getArgs &gt;&gt;= sequence_ . (map putStrLn) &lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sat, 12 May 2007 15:17:04 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3997</guid>
      <author>DRMacIver (David R. MacIver)</author>
    </item>
    <item>
      <title>JSON Parser in Haskell</title>
      <link>http://snippets.dzone.com/posts/show/3660</link>
      <description>I've been having trouble writing parsers recently, and I've been meaning to get to grips with Haskell at some point, so I figured I'd write a simple JSON parser using Haskell's Parsec library. Here's the code for it:&lt;br /&gt;&lt;br /&gt;Update: I've modified this to use Data.Map instead of a list of key value pairs for the record / object implementation. I've also removed the 'identifier' feature as it isn't really part of JSON proper. Also, I've noticed that this seems to have acquired some sort of presence on google. This isn't really very good code - it's more a demonstration of parsec than it is an actually useful parser. (I mean, it works fine, and it's probably sufficient for trivial uses, but I wouldn't e.g. guarantee it to be bug free). I strongly recommend using &lt;a href="http://www.lshift.net/blog/2006/07/13/writing-ajax-applications-in-haskell"&gt;this one&lt;/a&gt; instead. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import Text.ParserCombinators.Parsec&lt;br /&gt;import System&lt;br /&gt;import qualified Data.Map as Map&lt;br /&gt;&lt;br /&gt;-- Main method. Currently not very interesting - just a test piece of code which accepts&lt;br /&gt;-- a file and prints out a representation of the parsed type (or an error message if it is&lt;br /&gt;-- invalid.&lt;br /&gt;mainParser = do {&lt;br /&gt;    val &lt;- valueParser&lt;br /&gt;    ; skipMany space&lt;br /&gt;    ; eof&lt;br /&gt;    ; return val }&lt;br /&gt;&lt;br /&gt;main :: IO ()&lt;br /&gt;main = do {&lt;br /&gt;    args &lt;- getArgs &lt;br /&gt;  ; val &lt;- parseFromFile mainParser $ args !! 0 &lt;br /&gt;  ; print(val) } &lt;br /&gt;&lt;br /&gt;-- Matches string literals. &lt;br /&gt;literalString :: Parser JSON &lt;br /&gt;literalString = do {&lt;br /&gt;        char '"'&lt;br /&gt;      ;  val &lt;-  many1 letter&lt;br /&gt;      ;  char '"'&lt;br /&gt;      ; return $ LiteralString val}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- Data type representing a JSON AST. Roughly corresponds to a Javascript object.&lt;br /&gt;data JSON = ListValue [JSON] &lt;br /&gt;          | LiteralString String&lt;br /&gt;          | LiteralInt Integer&lt;br /&gt;          | LiteralBoolean Bool&lt;br /&gt;          | RecordValue (Map.Map String JSON)&lt;br /&gt;            deriving Show         &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- Combined parser.&lt;br /&gt;valueParser :: Parser JSON&lt;br /&gt;valueParser =       &lt;br /&gt;        literalString&lt;br /&gt;    &lt;|&gt; literalInt&lt;br /&gt;    &lt;|&gt; literalBoolean&lt;br /&gt;    &lt;|&gt; recordParser&lt;br /&gt;    &lt;|&gt; listParser &lt;br /&gt;&lt;br /&gt;-- Matches literal integers.&lt;br /&gt;literalInt :: Parser JSON&lt;br /&gt;literalInt = do {&lt;br /&gt;    ; val &lt;- many1 digit&lt;br /&gt;    ; return $ LiteralInt (read val)&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;-- Matches boolean literals&lt;br /&gt;literalBoolean :: Parser JSON&lt;br /&gt;literalBoolean =&lt;br /&gt;                do{ &lt;br /&gt;                  string "true"&lt;br /&gt;                ; return $ LiteralBoolean True}&lt;br /&gt;            &lt;|&gt; do{&lt;br /&gt;                  string "false"&lt;br /&gt;                ; return $ LiteralBoolean False}&lt;br /&gt;&lt;br /&gt;-- Code for parsing lists.&lt;br /&gt;-- Matches comma separated lists enclosed in [ ]&lt;br /&gt;listParser :: Parser JSON &lt;br /&gt;listParser = do{ &lt;br /&gt;                char '['&lt;br /&gt;              ; words &lt;- sepBy1 valueParser listSeparator&lt;br /&gt;              ; char ']'&lt;br /&gt;              ; return $ ListValue words&lt;br /&gt;              }&lt;br /&gt;&lt;br /&gt;-- Matches ',' with any amount of space on either side.&lt;br /&gt;listSeparator :: Parser ()&lt;br /&gt;listSeparator = do{ &lt;br /&gt;      skipMany space &lt;br /&gt;    ; char ','&lt;br /&gt;    ; skipMany space&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;-- Code for parsing records.&lt;br /&gt;-- Matches { word : JSON; word : JSON; word : value; ... }&lt;br /&gt;recordParser :: Parser JSON &lt;br /&gt;recordParser = do{&lt;br /&gt;      char '{'&lt;br /&gt;    ; defs &lt;- endBy definitionParser definitionSeparator&lt;br /&gt;    ; char '}'&lt;br /&gt;    ; return $ RecordValue $ Map.fromList defs &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;-- Matches things of the form word : JSON&lt;br /&gt;definitionParser :: Parser (String, JSON)&lt;br /&gt;definitionParser = do{&lt;br /&gt;      skipMany space&lt;br /&gt;    ; key &lt;- many1 letter &lt;br /&gt;    ; skipMany space&lt;br /&gt;    ; char ':'&lt;br /&gt;    ; skipMany space&lt;br /&gt;    ; val &lt;- valueParser&lt;br /&gt;    ; return (key, val)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;-- Matches ';' with any amount of space on either side.&lt;br /&gt;definitionSeparator :: Parser ()&lt;br /&gt;definitionSeparator = do {&lt;br /&gt;      skipMany space&lt;br /&gt;    ; char ';'&lt;br /&gt;    ; skipMany space&lt;br /&gt;    ; return () &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 11 Mar 2007 14:52:38 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3660</guid>
      <author>DRMacIver (David R. MacIver)</author>
    </item>
    <item>
      <title>&amp;lt;- and let .. = confusion</title>
      <link>http://snippets.dzone.com/posts/show/2131</link>
      <description>// description of your code here&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module Main&lt;br /&gt;   where&lt;br /&gt;&lt;br /&gt;import Random&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;main = do&lt;br /&gt;   -- Either of these work&lt;br /&gt;   --rnum &lt;- oneRandNum&lt;br /&gt;   let rnum = oneRandNum&lt;br /&gt;&lt;br /&gt;   -- But only let works here. Why?&lt;br /&gt;   --numbers &lt;- randArray&lt;br /&gt;   let numbers = randArray&lt;br /&gt;&lt;br /&gt;   -- Required for successful compilation.&lt;br /&gt;   print "foo"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;oneRandNum :: IO Int&lt;br /&gt;oneRandNum = getStdRandom( randomR( 0, 9 ) )&lt;br /&gt;&lt;br /&gt;randArray :: [IO Int]&lt;br /&gt;randArray = [oneRandNum]&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 01 Jun 2006 18:10:33 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2131</guid>
      <author>Dino ()</author>
    </item>
  </channel>
</rss>
