json-syntax (empty) → 0.1.0.0
raw patch · 8 files changed
+2454/−0 lines, 8 filesdep +aesondep +array-builderdep +array-chunkssetup-changed
Dependencies added: aeson, array-builder, array-chunks, base, byteslice, bytesmith, bytestring, gauge, json-syntax, neat-interpolation, primitive, scientific, scientific-notation, small-bytearray-builder, tasty, tasty-hunit, text, text-short, unordered-containers, vector
Files
- CHANGELOG.md +5/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- bench/Main.hs +27/−0
- common/Twitter100.hs +1866/−0
- json-syntax.cabal +89/−0
- src/Json.hs +344/−0
- test/Main.hs +91/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for json-syntax++## 0.1.0.0 -- 2020-01-20++* Initial release.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2019, Andrew Martin++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Andrew Martin nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ bench/Main.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE TypeApplications #-}++import Gauge.Main (defaultMain,bgroup,bench,whnf)++import Twitter100 (encodedTwitter100,byteStringTwitter100)++import qualified Data.Bytes as Bytes+import qualified Json as J+import qualified Data.Aeson as Aeson++main :: IO ()+main = defaultMain+ [ bgroup "json"+ [ bgroup "twitter"+ [ bench "100" $ whnf+ (\b -> J.decode (Bytes.fromByteArray b))+ encodedTwitter100+ ]+ ]+ , bgroup "aeson"+ [ bgroup "twitter"+ [ bench "100"+ (whnf (Aeson.decodeStrict' @Aeson.Value) byteStringTwitter100)+ ]+ ]+ ]
+ common/Twitter100.hs view
@@ -0,0 +1,1866 @@+{-# LANGUAGE QuasiQuotes #-}+module Twitter100+ ( encodedTwitter100+ , byteStringTwitter100+ ) where++import Data.ByteString (ByteString)+import Data.ByteString.Short (ShortByteString,toShort)+import Data.Primitive (ByteArray)+import Data.Text.Encoding (encodeUtf8)+import NeatInterpolation (text)++import qualified Data.Primitive as PM+import qualified Data.ByteString.Short.Internal as BSS++shortByteStringToByteArray :: ShortByteString -> ByteArray +shortByteStringToByteArray (BSS.SBS x) = PM.ByteArray x++encodedTwitter100 :: ByteArray+encodedTwitter100 =+ shortByteStringToByteArray (toShort byteStringTwitter100)++byteStringTwitter100 :: ByteString+byteStringTwitter100 = encodeUtf8+ [text|+ {+ "completed_in": 1.195569,+ "max_id": 30121530767708160,+ "max_id_str": "30121530767708160",+ "next_page": "?page=2&max_id=30121530767708160&rpp=100&q=haskell",+ "page": 1,+ "query": "haskell",+ "refresh_url": "?since_id=30121530767708160&q=haskell",+ "results": [+ {+ "created_at": "Wed, 26 Jan 2011 04:35:07 +0000",+ "from_user": "nicolaslara",+ "from_user_id": 3646730,+ "from_user_id_str": "3646730",+ "geo": null,+ "id": 30121530767708160,+ "id_str": "30121530767708160",+ "iso_language_code": "es",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/404973767/avatar_normal.jpg",+ "source": "<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>",+ "text": "@josej30 Python y Clojure. Obviamente son diferentes, y cada uno tiene sus ventajas y desventajas. De Haskell faltar\u00eda pattern matching",+ "to_user": "josej30",+ "to_user_id": 18616016,+ "to_user_id_str": "18616016"+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:30:38 +0000",+ "from_user": "pboudarga",+ "from_user_id": 207858021,+ "from_user_id_str": "207858021",+ "geo": null,+ "id": 30120402839666689,+ "id_str": "30120402839666689",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png",+ "source": "<a href="http://foursquare.com" rel="nofollow">foursquare</a>",+ "text": "I'm at Rolla Sushi Grill (27737 Bouquet Canyon Road, #106, Btw Haskell Canyon and Rosedell Drive, Saugus) http://4sq.com/gqqdhs",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:25:23 +0000",+ "from_user": "YNK33",+ "from_user_id": 69988683,+ "from_user_id_str": "69988683",+ "geo": null,+ "id": 30119083059978240,+ "id_str": "30119083059978240",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1211955817/avatar_7888_normal.gif",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "hsndfile 0.5.0: Free and open source Haskell bindings for libsndfile http://bit.ly/gHaBWG Mac Os",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:24:28 +0000",+ "from_user": "satzz",+ "from_user_id": 81492,+ "from_user_id_str": "81492",+ "geo": null,+ "id": 30118851488251904,+ "id_str": "30118851488251904",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/423894208/Picture_7_normal.jpg",+ "source": "<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>",+ "text": "Emacs\u306e\u30e2\u30fc\u30c9\u8868\u793a\u304c\u4eca(Ruby Controller Outputz RoR Flymake REl hs)\u3068\u306a\u3063\u3066\u3066\u3088\u304f\u308f\u304b\u3089\u306a\u3044\u3093\u3060\u3051\u3069\u6700\u5f8c\u306eREl\u3068\u304bhs\u3063\u3066\u4f55\u3060\u308d\u3046\u2026haskell\u3068\u304b2\u5e74\u4ee5\u4e0a\u66f8\u3044\u3066\u306a\u3044\u3051\u3069\u2026",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:19:19 +0000",+ "from_user": "planet_ocaml",+ "from_user_id": 9518356,+ "from_user_id_str": "9518356",+ "geo": null,+ "id": 30117557788741632,+ "id_str": "30117557788741632",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/119165723/ocaml-icon_normal.png",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "I so miss #haskell type classes in #ocaml - i want to do something like refinement. Also why does ocaml not have... http://bit.ly/geYRwt",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:16:32 +0000",+ "from_user": "aprikip",+ "from_user_id": 218059,+ "from_user_id_str": "218059",+ "geo": null,+ "id": 30116854940835840,+ "id_str": "30116854940835840",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1053837723/twitter-icon9_normal.jpg",+ "source": "<a href="http://sites.google.com/site/yorufukurou/" rel="nofollow">YoruFukurou</a>",+ "text": "yatex-mode\u3084haskell-mode\u306e\u3053\u3068\u3067\u3059\u306d\u3001\u308f\u304b\u308a\u307e\u3059\u3002",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:15:30 +0000",+ "from_user": "dysinger",+ "from_user_id": 216363,+ "from_user_id_str": "216363",+ "geo": null,+ "id": 30116594684264448,+ "id_str": "30116594684264448",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/72454310/Tim-Avatar_normal.png",+ "source": "<a href="http://www.nambu.com/" rel="nofollow">Nambu</a>",+ "text": "Haskell in Hawaii tonight for me... #fun",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:13:36 +0000",+ "from_user": "DanMil",+ "from_user_id": 1774820,+ "from_user_id_str": "1774820",+ "geo": null,+ "id": 30116117682851840,+ "id_str": "30116117682851840",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/61169291/dan_desert_thumb_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "@ojrac @chewedwire @tomheon Haskell isn't a language, it's a belief system. A seductive one...",+ "to_user": "ojrac",+ "to_user_id": 1594784,+ "to_user_id_str": "1594784"+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:11:06 +0000",+ "from_user": "djspiewak",+ "from_user_id": 659256,+ "from_user_id_str": "659256",+ "geo": null,+ "id": 30115488931520512,+ "id_str": "30115488931520512",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/746976711/angular-final_normal.jpg",+ "source": "<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>",+ "text": "One of the very nice things about Haskell as opposed to SML is the reduced proliferation of identifiers (e.g. andb, orb, etc). #typeclasses",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:06:12 +0000",+ "from_user": "listwarenet",+ "from_user_id": 144546280,+ "from_user_id_str": "144546280",+ "geo": null,+ "id": 30114255890026496,+ "id_str": "30114255890026496",+ "iso_language_code": "no",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/a/1295051201/images/default_profile_1_normal.png",+ "source": "<a href="http://1e10.org/cloud/" rel="nofollow">1e10</a>",+ "text": "http://www.listware.net/201101/haskell-cafe/84752-re-haskell-cafe-gpl-license-of-h-matrix-and-prelude-numeric.html Re: Haskell-c",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:01:29 +0000",+ "from_user": "ojrac",+ "from_user_id": 1594784,+ "from_user_id_str": "1594784",+ "geo": null,+ "id": 30113067333324800,+ "id_str": "30113067333324800",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/378515773/square-profile_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "RT @tomheon: @ojrac @chewedwire Don't worry, learning Haskell will not give you any clear idea what monad means.",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 04:00:13 +0000",+ "from_user": "ashleevelazq101",+ "from_user_id": 207589736,+ "from_user_id_str": "207589736",+ "geo": null,+ "id": 30112747555397632,+ "id_str": "30112747555397632",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/1225527428/headshot_1_normal.jpg",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "Federal investigation finds safety violations at The Acadia Hospital: By Meg Haskell, BDN Staff The investigatio... http://bit.ly/dONnpn",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:58:00 +0000",+ "from_user": "Hackage",+ "from_user_id": 17671137,+ "from_user_id_str": "17671137",+ "geo": null,+ "id": 30112192346984448,+ "id_str": "30112192346984448",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/290264834/Haskell-logo-outer-glow_normal.png",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "streams 0.4, added by EdwardKmett: Various Haskell 2010 stream comonads http://bit.ly/idBkPe",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:58:00 +0000",+ "from_user": "aapnoot",+ "from_user_id": 17489366,+ "from_user_id_str": "17489366",+ "geo": null,+ "id": 30112191881420800,+ "id_str": "30112191881420800",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "streams 0.4, added by EdwardKmett: Various Haskell 2010 stream comonads http://bit.ly/idBkPe",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:50:12 +0000",+ "from_user": "jeffmclamb",+ "from_user_id": 8530482,+ "from_user_id_str": "8530482",+ "geo": null,+ "id": 30110229207187456,+ "id_str": "30110229207187456",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/137867266/n608671563_7396_normal.jpg",+ "source": "<a href="http://friendfeed.com" rel="nofollow">FriendFeed</a>",+ "text": "Angel - daemon to run and monitor processes like daemontools or god, written in Haskell http://ff.im/-wNyLk",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:46:01 +0000",+ "from_user": "tomheon",+ "from_user_id": 177539201,+ "from_user_id_str": "177539201",+ "geo": null,+ "id": 30109174645919744,+ "id_str": "30109174645919744",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1178368800/img_normal.jpeg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "@ojrac @chewedwire Don't worry, learning Haskell will not give you any clear idea what monad means.",+ "to_user": "ojrac",+ "to_user_id": 1594784,+ "to_user_id_str": "1594784"+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:44:34 +0000",+ "from_user": "ojrac",+ "from_user_id": 1594784,+ "from_user_id_str": "1594784",+ "geo": null,+ "id": 30108808684503040,+ "id_str": "30108808684503040",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/378515773/square-profile_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "@chewedwire @tomheon Why are you making me curious about Haskell? I LIKE not knowing what monad means!!",+ "to_user": "chewedwire",+ "to_user_id": 128028225,+ "to_user_id_str": "128028225"+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:41:54 +0000",+ "from_user": "shokalshab",+ "from_user_id": 23750094,+ "from_user_id_str": "23750094",+ "geo": null,+ "id": 30108140443795456,+ "id_str": "30108140443795456",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "place": {+ "full_name": "Gymnastics Olympica USA, Van Nuys",+ "id": "4e4a2a2f86cb2946",+ "type_": "poi"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/951373780/Moeinthecar_normal.jpg",+ "source": "<a href="http://foursquare.com" rel="nofollow">foursquare</a>",+ "text": "I'm at Magnitude Cheer @ Gymnastics Olympica USA (7735 Haskell Ave., btw Saticoy & Strathern, Van Nuys) http://4sq.com/gmXfaL",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:41:35 +0000",+ "from_user": "Claricei",+ "from_user_id": 8135112,+ "from_user_id_str": "8135112",+ "geo": null,+ "id": 30108059208515584,+ "id_str": "30108059208515584",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1165240350/LIMITED_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "RT @kristenmchugh22: @KeithOlbermann Ryan looks like Jughead w/o the hat. And sounds as mealy-mouthed as Eddie Haskell.",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:40:02 +0000",+ "from_user": "chewedwire",+ "from_user_id": 128028225,+ "from_user_id_str": "128028225",+ "geo": null,+ "id": 30107670367182848,+ "id_str": "30107670367182848",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1224994593/Coding_Drunk_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "@tomheon Cool, I'll take a look. I feel like I should mention this: http://bit.ly/hVstDM",+ "to_user": "tomheon",+ "to_user_id": 177539201,+ "to_user_id_str": "177539201"+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:38:42 +0000",+ "from_user": "kristenmchugh22",+ "from_user_id": 8679778,+ "from_user_id_str": "8679778",+ "geo": null,+ "id": 30107332381777920,+ "id_str": "30107332381777920",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/1195318056/me_nyc_12_18_10_icon_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "@KeithOlbermann Ryan looks like Jughead w/o the hat. And sounds as mealy-mouthed as Eddie Haskell.",+ "to_user": "KeithOlbermann",+ "to_user_id": 756269,+ "to_user_id_str": "756269"+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:36:15 +0000",+ "from_user": "cityslikr",+ "from_user_id": 103316559,+ "from_user_id_str": "103316559",+ "geo": null,+ "id": 30106719153557504,+ "id_str": "30106719153557504",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1179458751/bc3beab4-d59d-4e78-b13b-50747986cfa2_normal.png",+ "source": "<a href="http://blackberry.com/twitter" rel="nofollow">Twitter for BlackBerry\u00ae</a>",+ "text": ""Social safety net into a hammock." So says Eddie Haskell with the GOP response. #SOTU",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:31:52 +0000",+ "from_user": "wrkforce_safety",+ "from_user_id": 169063143,+ "from_user_id_str": "169063143",+ "geo": null,+ "id": 30105614919143424,+ "id_str": "30105614919143424",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1160506212/9697_1_normal.gif",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "Federal investigation finds safety violations at The Acadia Hospital: By Meg Haskell, BDN Staff The investigatio... http://bit.ly/gA60C1",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:29:40 +0000",+ "from_user": "tomheon",+ "from_user_id": 177539201,+ "from_user_id_str": "177539201",+ "geo": null,+ "id": 30105060960632832,+ "id_str": "30105060960632832",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1178368800/img_normal.jpeg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "@chewedwire Great book on Haskell: http://oreilly.com/catalog/9780596514983",+ "to_user": "chewedwire",+ "to_user_id": 128028225,+ "to_user_id_str": "128028225"+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:29:19 +0000",+ "from_user": "turnageb",+ "from_user_id": 782692,+ "from_user_id_str": "782692",+ "geo": null,+ "id": 30104974591533057,+ "id_str": "30104974591533057",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1031304589/Profile.2007.1_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "RT @ovillalon: Paul Ryan solves the mystery of whatever happened to Eddie Haskell. #sotu",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:28:04 +0000",+ "from_user": "chewedwire",+ "from_user_id": 128028225,+ "from_user_id_str": "128028225",+ "geo": null,+ "id": 30104657267265536,+ "id_str": "30104657267265536",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1224994593/Coding_Drunk_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "@tomheon I always loved the pattern matching in SML and it looks like Haskell is MUCH better at it. I'm messing around now at tryhaskell.org",+ "to_user": "tomheon",+ "to_user_id": 177539201,+ "to_user_id_str": "177539201"+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:28:01 +0000",+ "from_user": "ovillalon",+ "from_user_id": 12834082,+ "from_user_id_str": "12834082",+ "geo": null,+ "id": 30104647213518848,+ "id_str": "30104647213518848",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/1083036140/mugshot_normal.png",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "Paul Ryan solves the mystery of whatever happened to Eddie Haskell. #sotu",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:26:02 +0000",+ "from_user": "goodfox",+ "from_user_id": 13540930,+ "from_user_id_str": "13540930",+ "geo": null,+ "id": 30104146455560192,+ "id_str": "30104146455560192",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1205312219/23467_350321383101_821143101_5114147_3010041_n_normal.jpg",+ "source": "<a href="http://www.ubertwitter.com/bb/download.php" rel="nofollow">\u00dcberTwitter</a>",+ "text": "@billykeene22 Bordeaux is one of my heroes. I was so excited when he accepted the invitation to campus. He's been a great friend to Haskell.",+ "to_user": "billykeene22",+ "to_user_id": 10226179,+ "to_user_id_str": "10226179"+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:25:18 +0000",+ "from_user": "josej30",+ "from_user_id": 18616016,+ "from_user_id_str": "18616016",+ "geo": null,+ "id": 30103962313031681,+ "id_str": "30103962313031681",+ "iso_language_code": "es",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1173522726/214397343_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "@cris7ian Ahh bueno multiparadigma ya es respetable :) Empezar\u00e9 a explotar la parte funcional de los lenguajes ahora #Haskell",+ "to_user": "Cris7ian",+ "to_user_id": 14870909,+ "to_user_id_str": "14870909"+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:23:43 +0000",+ "from_user": "Cris7ian",+ "from_user_id": 14870909,+ "from_user_id_str": "14870909",+ "geo": null,+ "id": 30103562360983553,+ "id_str": "30103562360983553",+ "iso_language_code": "es",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1176930429/oso_yo_normal.png",+ "source": "<a href="http://www.echofon.com/" rel="nofollow">Echofon</a>",+ "text": "@josej30 hahaha no, es multiparadigma y es bastante lazy. Nothing like haskell, pero s\u00ed, el de Flash",+ "to_user": "josej30",+ "to_user_id": 18616016,+ "to_user_id_str": "18616016"+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:20:24 +0000",+ "from_user": "ernestgrumbles",+ "from_user_id": 2421643,+ "from_user_id_str": "2421643",+ "geo": null,+ "id": 30102730756333568,+ "id_str": "30102730756333568",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1190361665/ernestgrumbles-17_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "Wow... WolframAlpha did not know who Eddie Haskell is. Guess I'll never use that "knowledge engine" again.",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:14:21 +0000",+ "from_user": "chewedwire",+ "from_user_id": 128028225,+ "from_user_id_str": "128028225",+ "geo": null,+ "id": 30101204428132352,+ "id_str": "30101204428132352",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1224994593/Coding_Drunk_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "@tomheon How is Haskell better/different from CL or Scheme? I honestly don't know, although I'm becoming more curious.",+ "to_user": "tomheon",+ "to_user_id": 177539201,+ "to_user_id_str": "177539201"+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:06:54 +0000",+ "from_user": "goodfox",+ "from_user_id": 13540930,+ "from_user_id_str": "13540930",+ "geo": null,+ "id": 30099329809129473,+ "id_str": "30099329809129473",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1205312219/23467_350321383101_821143101_5114147_3010041_n_normal.jpg",+ "source": "<a href="http://www.ubertwitter.com/bb/download.php" rel="nofollow">\u00dcberTwitter</a>",+ "text": "A day of vision & speeches. #SOTU now. And a wonderful Haskell Convocation address earlier today by Sinte Gleske President Lionel Bordeaux.",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 03:03:38 +0000",+ "from_user": "LaLiciouz_03",+ "from_user_id": 119185220,+ "from_user_id_str": "119185220",+ "geo": null,+ "id": 30098510623805440,+ "id_str": "30098510623805440",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1089027228/dfg_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "The Game with the girl room 330 Haskell follow us...",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 02:57:25 +0000",+ "from_user": "josej30",+ "from_user_id": 18616016,+ "from_user_id_str": "18616016",+ "geo": null,+ "id": 30096946144215040,+ "id_str": "30096946144215040",+ "iso_language_code": "es",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1173522726/214397343_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "Voy a extra\u00f1ar Haskell cuando regrese al mundo imperativo. Hay alg\u00fan lenguaje imperativo que tenga este poder funcional? #ci3661",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 02:55:32 +0000",+ "from_user": "Hackage",+ "from_user_id": 17671137,+ "from_user_id_str": "17671137",+ "geo": null,+ "id": 30096471814574080,+ "id_str": "30096471814574080",+ "iso_language_code": "no",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/290264834/Haskell-logo-outer-glow_normal.png",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "comonad-transformers 0.9.0, added by EdwardKmett: Haskell 98 comonad transformers http://bit.ly/h6xIsf",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 02:48:12 +0000",+ "from_user": "tomheon",+ "from_user_id": 177539201,+ "from_user_id_str": "177539201",+ "geo": null,+ "id": 30094626920603649,+ "id_str": "30094626920603649",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1178368800/img_normal.jpeg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "Every time I look at Haskell I love it more.",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 02:40:42 +0000",+ "from_user": "r_takaishi",+ "from_user_id": 60792568,+ "from_user_id_str": "60792568",+ "geo": null,+ "id": 30092735935422464,+ "id_str": "30092735935422464",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1203647517/glenda-flash_normal.jpg",+ "source": "<a href="http://twmode.sf.net/" rel="nofollow">twmode</a>",+ "text": "Haskell\u3088\u308aD\u8a00\u8a9e\u304c\u4e0a\u3068\u306f\u601d\u308f\u306a\u304b\u3063\u305f\uff0e http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 02:39:31 +0000",+ "from_user": "wtp1787",+ "from_user_id": 160145510,+ "from_user_id_str": "160145510",+ "geo": null,+ "id": 30092439653974018,+ "id_str": "30092439653974018",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1218108166/going_galt_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "RT @KLSouth: Eddie Haskell Goes to Washington... "You look really nice tonight, Ms Cleaver"",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 02:39:20 +0000",+ "from_user": "MelissaRNMBA",+ "from_user_id": 96616016,+ "from_user_id_str": "96616016",+ "geo": null,+ "id": 30092392203816960,+ "id_str": "30092392203816960",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1196978169/Picture0002_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "@KLSouth At least Eddie Haskell was entertaining.",+ "to_user": "KLSouth",+ "to_user_id": 14862975,+ "to_user_id_str": "14862975"+ },+ {+ "created_at": "Wed, 26 Jan 2011 02:38:29 +0000",+ "from_user": "KLSouth",+ "from_user_id": 14862975,+ "from_user_id_str": "14862975",+ "geo": null,+ "id": 30092178327871489,+ "id_str": "30092178327871489",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/421596393/kls_4_normal.JPG",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "Eddie Haskell Goes to Washington... "You look really nice tonight, Ms Cleaver"",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 02:36:17 +0000",+ "from_user": "listwarenet",+ "from_user_id": 144546280,+ "from_user_id_str": "144546280",+ "geo": null,+ "id": 30091626869161984,+ "id_str": "30091626869161984",+ "iso_language_code": "no",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/a/1295051201/images/default_profile_1_normal.png",+ "source": "<a href="http://1e10.org/cloud/" rel="nofollow">1e10</a>",+ "text": "http://www.listware.net/201101/haskell-beginners/84641-haskell-beginners-wildcards-in-expressions.html Haskell-beginners - Wild",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 02:23:14 +0000",+ "from_user": "dbph",+ "from_user_id": 24538048,+ "from_user_id_str": "24538048",+ "geo": null,+ "id": 30088341030440960,+ "id_str": "30088341030440960",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1117267605/rope_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "RT @dnene: Skilled Calisthenics. Haskell code that outputs python which spits ruby which emits the haskell source. http://j.mp/YlQUL via @mfeathers",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 01:58:31 +0000",+ "from_user": "YubaVetTech",+ "from_user_id": 158951567,+ "from_user_id_str": "158951567",+ "geo": null,+ "id": 30082124207886336,+ "id_str": "30082124207886336",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/962721419/Logo_3_normal.jpg",+ "source": "<a href="http://www.facebook.com/twitter" rel="nofollow">Facebook</a>",+ "text": "Dr. Haskell has just been awarded the prestigious Hayward Award for \u2018Excellence in Education\u2019. This award honors... http://fb.me/QgQCxd74",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 01:56:04 +0000",+ "from_user": "YubaVetTech",+ "from_user_id": 158951567,+ "from_user_id_str": "158951567",+ "geo": null,+ "id": 30081505476743168,+ "id_str": "30081505476743168",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/962721419/Logo_3_normal.jpg",+ "source": "<a href="http://www.facebook.com/twitter" rel="nofollow">Facebook</a>",+ "text": "Dr. Haskell has just been awarded the prestigous Haward Award for Excellence in Education. This award honors... http://fb.me/PC9mYmCR",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 01:43:50 +0000",+ "from_user": "Verus",+ "from_user_id": 2331498,+ "from_user_id_str": "2331498",+ "geo": null,+ "id": 30078427155406848,+ "id_str": "30078427155406848",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/494632120/me_normal.jpg",+ "source": "<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>",+ "text": "@kami_joe \u3044\u3084\uff0c\u8ab2\u984c\u306f\u89e3\u6c7a\u5bfe\u8c61(\u30d1\u30ba\u30eb\u3068\u304b)\u3092\u4e0e\u3048\u3089\u308c\u3066\uff0c\u554f\u984c\u5b9a\u7fa9\u3068\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0(\u6307\u5b9a\u8a00\u8a9e\u306fC++\u3082\u3057\u304f\u306fJava)\u3068\u3044\u3046\u3044\u308f\u3070\u666e\u901a\u306a\u8ab2\u984c\u3067\u306f\u3042\u308b\u3093\u3060\u3051\u3069\uff0e\u95a2\u6570\u578b\u8a00\u8a9e\u306fHaskell\u306e\u6388\u696d\u304c\u307e\u305f\u5225\u306b\u3042\u308b\u306e\uff0e",+ "to_user": "kami_joe",+ "to_user_id": 79273052,+ "to_user_id_str": "79273052"+ },+ {+ "created_at": "Wed, 26 Jan 2011 01:40:37 +0000",+ "from_user": "cz_newdrafts",+ "from_user_id": 79151233,+ "from_user_id_str": "79151233",+ "geo": null,+ "id": 30077617361125376,+ "id_str": "30077617361125376",+ "iso_language_code": "no",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/a/1295051201/images/default_profile_2_normal.png",+ "source": "<a href="http://tommorris.org/" rel="nofollow">tommorris' hacksample</a>",+ "text": "Haskell programming language http://bit.ly/gpPAwB",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 01:02:57 +0000",+ "from_user": "Verus",+ "from_user_id": 2331498,+ "from_user_id_str": "2331498",+ "geo": null,+ "id": 30068139416879104,+ "id_str": "30068139416879104",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/494632120/me_normal.jpg",+ "source": "<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>",+ "text": "@shukukei Java\u3068C\u306f\u3042\u308b\u7a0b\u5ea6\u66f8\u3051\u3066\u3042\u305f\u308a\u307e\u3048\u306a\u3068\u3053\u308d\u304c\u3042\u308b\u304b\u3089\u306a\u30fc\uff0ePython\u306f\u500b\u4eba\u7684\u306b\u611f\u899a\u304c\u5408\u308f\u306a\u3044\uff0e\u611f\u899a\u306a\u306e\u3067\uff0c\u3082\u3046\u3069\u3046\u3057\u3088\u3046\u3082\u306a\u3044\uff57 \u3044\u307e\u306fScala\u3068Haskell\u3092\u3082\u3063\u3068\u6975\u3081\u305f\u3044\u3068\u3053\u308d\uff0e",+ "to_user": "shukukei",+ "to_user_id": 9252720,+ "to_user_id_str": "9252720"+ },+ {+ "created_at": "Wed, 26 Jan 2011 01:02:35 +0000",+ "from_user": "joeyhess",+ "from_user_id": 2781460,+ "from_user_id_str": "2781460",+ "geo": null,+ "id": 30068046538219520,+ "id_str": "30068046538219520",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/82526625/.joeyicon_normal.jpg",+ "source": "<a href="http://identi.ca" rel="nofollow">identica</a>",+ "text": "just figured out that I can use parameterized types to remove a dependency loop in git-annex's type definitions. whee #haskell",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:54:22 +0000",+ "from_user": "listwarenet",+ "from_user_id": 144546280,+ "from_user_id_str": "144546280",+ "geo": null,+ "id": 30065977920061440,+ "id_str": "30065977920061440",+ "iso_language_code": "no",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/a/1295051201/images/default_profile_1_normal.png",+ "source": "<a href="http://1e10.org/cloud/" rel="nofollow">1e10</a>",+ "text": "http://www.listware.net/201101/haskell-beginners/84466-haskell-beginners-bytestring-question.html Haskell-beginners - Bytestrin",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:52:07 +0000",+ "from_user": "_aaron_",+ "from_user_id": 1291845,+ "from_user_id_str": "1291845",+ "geo": null,+ "id": 30065412242669568,+ "id_str": "30065412242669568",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1225743404/ThinOxygen-small-opaque-solidarity_normal.png",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "wanted: librly licensed high level native compiled lang with min runtime (otherwise cobra/mono would be perfect) for win. lua? haskell? ooc?",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:45:45 +0000",+ "from_user": "shelarcy",+ "from_user_id": 5912444,+ "from_user_id_str": "5912444",+ "geo": null,+ "id": 30063810773516288,+ "id_str": "30063810773516288",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/546261026/ssf0xg11_normal.jpg",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "RT @Hackage: download 0.3.1.1, added by MagnusTherning: High-level file download based on URLs http://bit.ly/eHfiJB",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:41:00 +0000",+ "from_user": "kudzu_naoki",+ "from_user_id": 135993,+ "from_user_id_str": "135993",+ "geo": null,+ "id": 30062613287141376,+ "id_str": "30062613287141376",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1190667086/myface2010small_normal.jpg",+ "source": "<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>",+ "text": "RT @tanakh: \u9b54\u6cd5Haskell\u5c11\u5973\u5019\u88dc\u3092\u63a2\u3059\u306e\u3082\u5927\u5909\u306a\u3093\u3060",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:40:25 +0000",+ "from_user": "omasanori",+ "from_user_id": 52620546,+ "from_user_id_str": "52620546",+ "geo": null,+ "id": 30062465656033280,+ "id_str": "30062465656033280",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/434693356/twitter-icon_normal.png",+ "source": "<a href="http://www.movatwi.jp" rel="nofollow">www.movatwi.jp</a>",+ "text": "\u9b54\u6cd5Haskell\u5c11\u5973\u306e\u4e00\u65e5\u306fGHC HEAD\u306e\u30d3\u30eb\u30c9\u304b\u3089\u59cb\u307e\u308b",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:37:12 +0000",+ "from_user": "omasanori",+ "from_user_id": 52620546,+ "from_user_id_str": "52620546",+ "geo": null,+ "id": 30061656331526144,+ "id_str": "30061656331526144",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/434693356/twitter-icon_normal.png",+ "source": "<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>",+ "text": "RT @tanakh: \u50d5\u3068\u5951\u7d04\u3057\u3066\u9b54\u6cd5Haskell\u5c11\u5973\u306b\u306a\u308d\u3046\u3088\uff01",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:35:42 +0000",+ "from_user": "kudzu_naoki",+ "from_user_id": 135993,+ "from_user_id_str": "135993",+ "geo": null,+ "id": 30061282665168896,+ "id_str": "30061282665168896",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1190667086/myface2010small_normal.jpg",+ "source": "<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>",+ "text": "RT @tanakh: \u50d5\u3068\u5951\u7d04\u3057\u3066\u9b54\u6cd5Haskell\u5c11\u5973\u306b\u306a\u308d\u3046\u3088\uff01",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:30:02 +0000",+ "from_user": "qnighy",+ "from_user_id": 1631333,+ "from_user_id_str": "1631333",+ "geo": null,+ "id": 30059855884582913,+ "id_str": "30059855884582913",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/81268862/profile300_normal.jpg",+ "source": "<a href="http://www.hootsuite.com" rel="nofollow">HootSuite</a>",+ "text": "RT @tanakh: \u50d5\u3068\u5951\u7d04\u3057\u3066\u9b54\u6cd5Haskell\u5c11\u5973\u306b\u306a\u308d\u3046\u3088\uff01",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:26:20 +0000",+ "from_user": "phdwine",+ "from_user_id": 9093754,+ "from_user_id_str": "9093754",+ "geo": null,+ "id": 30058925516656640,+ "id_str": "30058925516656640",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/99435906/PHD_3d_col_blk_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "Last weekend of Tri Nations Tasting with PHD wines at Haskell Vineyards. Hope you didn't miss the Pinot Noir tasting last week !",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:21:14 +0000",+ "from_user": "djay75",+ "from_user_id": 2119923,+ "from_user_id_str": "2119923",+ "geo": null,+ "id": 30057639543050240,+ "id_str": "30057639543050240",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1096701078/djayprofile_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "RT @dnene: Skilled Calisthenics. Haskell code that outputs python which spits ruby which emits the haskell source. http://j.mp/YlQUL via @mfeathers",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:19:30 +0000",+ "from_user": "PrinceOfBrkeley",+ "from_user_id": 134323731,+ "from_user_id_str": "134323731",+ "geo": null,+ "id": 30057205554216960,+ "id_str": "30057205554216960",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1225818824/IMG00518-20110125-1547_normal.jpg",+ "source": "<a href="http://blackberry.com/twitter" rel="nofollow">Twitter for BlackBerry\u00ae</a>",+ "text": "@PayThaPrince go to haskell.",+ "to_user": "PayThaPrince",+ "to_user_id": 167093027,+ "to_user_id_str": "167093027"+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:03:28 +0000",+ "from_user": "bennadel",+ "from_user_id": 705857,+ "from_user_id_str": "705857",+ "geo": null,+ "id": 30053166972141569,+ "id_str": "30053166972141569",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/429483912/ben_twitter_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "Using #Homebrew to install Haskell - the last of the Seven Languages (in Seven Weeks) http://bit.ly/eA9Cv1 This has been some journey.",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Wed, 26 Jan 2011 00:02:54 +0000",+ "from_user": "simonszu",+ "from_user_id": 251466,+ "from_user_id_str": "251466",+ "geo": null,+ "id": 30053025502466048,+ "id_str": "30053025502466048",+ "iso_language_code": "de",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1194100934/pass_normal.jpg",+ "source": "<a href="http://www.echofon.com/" rel="nofollow">Echofon</a>",+ "text": "Ouh yeah! Ich werde doch produktiv sein, diese Semesterferien. Ich werde funktional Programmieren lernen. #haskell, Baby.",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:59:13 +0000",+ "from_user": "diligiant",+ "from_user_id": 357786,+ "from_user_id_str": "357786",+ "geo": null,+ "id": 30052100973006848,+ "id_str": "30052100973006848",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/612044841/FM_2010_normal.jpg",+ "source": "<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>",+ "text": "RT @paulrbrown: "...we only discovered a single bug after compilation." (http://t.co/K0wlEYz) #haskell",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:54:46 +0000",+ "from_user": "wlad_kent",+ "from_user_id": 101597523,+ "from_user_id_str": "101597523",+ "geo": null,+ "id": 30050977964892160,+ "id_str": "30050977964892160",+ "iso_language_code": "pt",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1206183256/2010-12-12-204902_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "@Nilson_Neto Isso eh bem basico. quando vc estiver estudando recurs\u00e3o em Haskell, ai vc vai ver oq eh papo de nerd - kkk - 1\u00ba periodo isso.",+ "to_user": "Nilson_Neto",+ "to_user_id": 86297184,+ "to_user_id_str": "86297184"+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:51:22 +0000",+ "from_user": "listwarenet",+ "from_user_id": 144546280,+ "from_user_id_str": "144546280",+ "geo": null,+ "id": 30050123383832577,+ "id_str": "30050123383832577",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/a/1295051201/images/default_profile_1_normal.png",+ "source": "<a href="http://1e10.org/cloud/" rel="nofollow">1e10</a>",+ "text": "http://www.listware.net/201101/haskell-cafe/84336-haskell-cafe-monomorphic-let-bindings-and-darcs.html Haskell-cafe - Monomorph",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:48:40 +0000",+ "from_user": "lsbardel",+ "from_user_id": 5776901,+ "from_user_id_str": "5776901",+ "geo": null,+ "id": 30049446469312512,+ "id_str": "30049446469312512",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/472682157/lucabw_normal.JPG",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "Very interesting technology stack these guys use http://bit.ly/ghAjS7 #python #redis #haskell",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:45:48 +0000",+ "from_user": "pmonks",+ "from_user_id": 3005901,+ "from_user_id_str": "3005901",+ "geo": null,+ "id": 30048721110573056,+ "id_str": "30048721110573056",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/278943006/Lone_Pine_Peak_-_Peter_200x200_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "@techielicous Haskell: http://bit.ly/gy3oFi ;-)",+ "to_user": "techielicous",+ "to_user_id": 203834278,+ "to_user_id_str": "203834278"+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:44:47 +0000",+ "from_user": "TheRonaldMCD",+ "from_user_id": 162697074,+ "from_user_id_str": "162697074",+ "geo": null,+ "id": 30048468781244416,+ "id_str": "30048468781244416",+ "iso_language_code": "no",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/826205838/ryan3_normal.jpg",+ "source": "<a href="http://foursquare.com" rel="nofollow">foursquare</a>",+ "text": "I'm at Aldi Food Market (4122 Gaston Ave, Haskell, Dallas) http://4sq.com/ekqRY7",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:44:04 +0000",+ "from_user": "techielicous",+ "from_user_id": 203834278,+ "from_user_id_str": "203834278",+ "geo": null,+ "id": 30048286589067264,+ "id_str": "30048286589067264",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1223375080/me_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "@pmonks I was thinking Haskell or Scheme",+ "to_user": "pmonks",+ "to_user_id": 3005901,+ "to_user_id_str": "3005901"+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:38:14 +0000",+ "from_user": "nushio",+ "from_user_id": 537690,+ "from_user_id_str": "537690",+ "geo": null,+ "id": 30046818658164737,+ "id_str": "30046818658164737",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/45665122/nushiostamp_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "\u305d\u3046\u3044\u3084\u5951\u7d04\u306b\u3088\u308b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3068\u304b\u3042\u3063\u305f\u306a\u3002Haskell\u306a\u3093\u304b\u3088\u308a\u3042\u3063\u3061\u306e\u65b9\u304c\u9b54\u6cd5\u5c11\u5973\u547c\u3070\u308f\u308a\u306b\u3075\u3055\u308f\u3057\u3044\u3002",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:38:03 +0000",+ "from_user": "aodag",+ "from_user_id": 181192,+ "from_user_id_str": "181192",+ "geo": null,+ "id": 30046772223016960,+ "id_str": "30046772223016960",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1089890701/q530888600_9828_normal.jpg",+ "source": "<a href="http://www.movatwi.jp" rel="nofollow">www.movatwi.jp</a>",+ "text": "RT @omasanori: \u300c\u3082\u3046\u4f55\u5e74\u3082Haskell\u306e\u3053\u3068\u3057\u304b\u8003\u3048\u3066\u306a\u304b\u3063\u305f\u304b\u3089\u306a\u3001\u30eb\u30fc\u30d7\u306e\u4f7f\u3044\u65b9\u5fd8\u308c\u3066\u305f\u300d",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:37:53 +0000",+ "from_user": "kanaya",+ "from_user_id": 5886055,+ "from_user_id_str": "5886055",+ "geo": null,+ "id": 30046729243983873,+ "id_str": "30046729243983873",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/85531669/ichi_normal.jpg",+ "source": "<a href="http://itunes.apple.com/app/twitter/id333903271?mt=8" rel="nofollow">Twitter for iPad</a>",+ "text": "\u9e97\u3057\u3044\u3002\u201c@omasanori: \u300c\u3082\u3046\u4f55\u5e74\u3082Haskell\u306e\u3053\u3068\u3057\u304b\u8003\u3048\u3066\u306a\u304b\u3063\u305f\u304b\u3089\u306a\u3001\u30eb\u30fc\u30d7\u306e\u4f7f\u3044\u65b9\u5fd8\u308c\u3066\u305f\u300d\u201d",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:36:26 +0000",+ "from_user": "omasanori",+ "from_user_id": 52620546,+ "from_user_id_str": "52620546",+ "geo": null,+ "id": 30046367187476481,+ "id_str": "30046367187476481",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/434693356/twitter-icon_normal.png",+ "source": "<a href="http://www.movatwi.jp" rel="nofollow">www.movatwi.jp</a>",+ "text": "\u300c\u3082\u3046\u4f55\u5e74\u3082Haskell\u306e\u3053\u3068\u3057\u304b\u8003\u3048\u3066\u306a\u304b\u3063\u305f\u304b\u3089\u306a\u3001\u30eb\u30fc\u30d7\u306e\u4f7f\u3044\u65b9\u5fd8\u308c\u3066\u305f\u300d",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:16:13 +0000",+ "from_user": "finalfusion",+ "from_user_id": 1659992,+ "from_user_id_str": "1659992",+ "geo": null,+ "id": 30041278544609280,+ "id_str": "30041278544609280",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/504488750/1_normal.jpg",+ "source": "<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>",+ "text": "RT @necocen: Haskell\u306e\u30df\u30b5\u30ef\u3001\u3068\u3044\u3046\u3082\u306e\u3092\u8003\u3048\u3066\u307f\u3066\u3071\u3063\u3068\u3057\u306a\u3044",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:05:09 +0000",+ "from_user": "mikehadlow",+ "from_user_id": 272513,+ "from_user_id_str": "272513",+ "geo": null,+ "id": 30038492373319680,+ "id_str": "30038492373319680",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/320244078/Mike_Painting2_normal.png",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": "Just written the same simple program in C#, F# and Haskell: 18, 12 and 9 LoC respectively. And I'm much better at C# than F# or Haskell.",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 23:01:28 +0000",+ "from_user": "newsportlandme",+ "from_user_id": 89393264,+ "from_user_id_str": "89393264",+ "geo": null,+ "id": 30037564589084673,+ "id_str": "30037564589084673",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1169486472/020_portland_me_normal.jpg",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "Governor's Choice to Run Maine DOC Under Scrutiny - MPBN: State Rep. Anne Haskell, a Portland Democrat, says Mai... http://bit.ly/fO30gC",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:59:55 +0000",+ "from_user": "michaelneale",+ "from_user_id": 38138,+ "from_user_id_str": "38138",+ "geo": null,+ "id": 30037174615281664,+ "id_str": "30037174615281664",+ "iso_language_code": "no",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/1212565885/Screen_shot_2011-01-11_at_5.28.47_PM_normal.png",+ "source": "<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>",+ "text": "The haskell EvilMangler http://t.co/P2Tls7J",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:45:06 +0000",+ "from_user": "karno",+ "from_user_id": 45692,+ "from_user_id_str": "45692",+ "geo": null,+ "id": 30033448286552064,+ "id_str": "30033448286552064",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/profile_images/1177741507/dogkarno_r_normal.jpg",+ "source": "<a href="http://yubitter.com/" rel="nofollow">yubitter</a>",+ "text": "Haskell\u3063\u3066\u95a2\u6570\u306b\u30ab\u30ec\u30fc\u7c89\u3076\u3061\u8fbc\u3080\u3068\u304b\u306a\u3093\u3068\u304b",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:44:23 +0000",+ "from_user": "celeron1ghz",+ "from_user_id": 27605,+ "from_user_id_str": "27605",+ "geo": null,+ "id": 30033268761956352,+ "id_str": "30033268761956352",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/15826632/meron_normal.jpg",+ "source": "<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>",+ "text": "RT @necocen: Haskell\u306e\u30df\u30b5\u30ef\u3001\u3068\u3044\u3046\u3082\u306e\u3092\u8003\u3048\u3066\u307f\u3066\u3071\u3063\u3068\u3057\u306a\u3044",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:43:30 +0000",+ "from_user": "necocen",+ "from_user_id": 12901,+ "from_user_id_str": "12901",+ "geo": null,+ "id": 30033044035346432,+ "id_str": "30033044035346432",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/56091349/haruhi_nagato-Y_normal.jpg",+ "source": "<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>",+ "text": "\u307e\u3042Haskell\u77e5\u3089\u3093\u3057\u306d",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:42:54 +0000",+ "from_user": "necocen",+ "from_user_id": 12901,+ "from_user_id_str": "12901",+ "geo": null,+ "id": 30032894856531968,+ "id_str": "30032894856531968",+ "iso_language_code": "ja",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/56091349/haruhi_nagato-Y_normal.jpg",+ "source": "<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>",+ "text": "Haskell\u306e\u30df\u30b5\u30ef\u3001\u3068\u3044\u3046\u3082\u306e\u3092\u8003\u3048\u3066\u307f\u3066\u3071\u3063\u3068\u3057\u306a\u3044",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:35:09 +0000",+ "from_user": "jjedMoriAnktah",+ "from_user_id": 10821270,+ "from_user_id_str": "10821270",+ "geo": null,+ "id": 30030942106025984,+ "id_str": "30030942106025984",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1195474259/Salto_Marlon_normal.jpg",+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",+ "text": ""A Haskell program that outputs a Python program that outputs a Ruby program that outputs the original Haskell program" http://is.gd/E6Julu",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:34:30 +0000",+ "from_user": "comatose_kid",+ "from_user_id": 7554762,+ "from_user_id_str": "7554762",+ "geo": null,+ "id": 30030780205899776,+ "id_str": "30030780205899776",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/100515212/ajay-photo_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "RT @bumptech: Bump Dev Blog - Why we use Haskell at Bump http://devblog.bu.mp/haskell-at-bump",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:29:19 +0000",+ "from_user": "landmvintage",+ "from_user_id": 148474705,+ "from_user_id_str": "148474705",+ "geo": null,+ "id": 30029476003840000,+ "id_str": "30029476003840000",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/1119234716/fur_hat_-_gilbeys_vodka_-_life_-_11-30-1962_normal.JPG",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "RT @faerymoongodess: Magnificent Miriam Haskell Baroque Pearl Necklace by @MercyMadge http://etsy.me/hqRl51",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:24:52 +0000",+ "from_user": "faerymoongodess",+ "from_user_id": 37715508,+ "from_user_id_str": "37715508",+ "geo": null,+ "id": 30028356326002688,+ "id_str": "30028356326002688",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1207891411/ballerina_normal.jpg",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "Magnificent Miriam Haskell Baroque Pearl Necklace by @MercyMadge http://etsy.me/hqRl51",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:17:16 +0000",+ "from_user": "Hackage",+ "from_user_id": 17671137,+ "from_user_id_str": "17671137",+ "geo": null,+ "id": 30026442456694784,+ "id_str": "30026442456694784",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/290264834/Haskell-logo-outer-glow_normal.png",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "base16-bytestring 0.1.0.0, added by BryanOSullivan: Fast base16 (hex) encoding and deconding for ByteStrings http://bit.ly/eu75TN",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:12:07 +0000",+ "from_user": "benreads",+ "from_user_id": 199750997,+ "from_user_id_str": "199750997",+ "geo": null,+ "id": 30025146991382528,+ "id_str": "30025146991382528",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png",+ "source": "<a href="http://twitter.com/">web</a>",+ "text": "Writing Systems Software in a Functional Language -- brief, but fun. I want to see how well they can make Systems Haskell perform at scale.",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:09:45 +0000",+ "from_user": "jcawthorne1",+ "from_user_id": 35359797,+ "from_user_id_str": "35359797",+ "geo": null,+ "id": 30024549265309696,+ "id_str": "30024549265309696",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1173453785/48893_521140819_1896062_q_normal.jpg",+ "source": "<a href="http://twitter.com/" rel="nofollow">Twitter for iPhone</a>",+ "text": "Just saw Jeff Haskell give the middle finger!! Lol awesome",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:06:44 +0000",+ "from_user": "goodfox",+ "from_user_id": 13540930,+ "from_user_id_str": "13540930",+ "geo": null,+ "id": 30023790381498369,+ "id_str": "30023790381498369",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1205312219/23467_350321383101_821143101_5114147_3010041_n_normal.jpg",+ "source": "<a href="http://foursquare.com" rel="nofollow">foursquare</a>",+ "text": "At the Haskell Convocation. (@ Haskell Indian Nations U Auditorium) http://4sq.com/eKKXyn",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 22:02:31 +0000",+ "from_user": "sanityinc",+ "from_user_id": 14674418,+ "from_user_id_str": "14674418",+ "geo": null,+ "id": 30022731919523840,+ "id_str": "30022731919523840",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/238230125/IMG_1030-1_normal.jpg",+ "source": "<a href="http://www.echofon.com/" rel="nofollow">Echofon</a>",+ "text": "@xshay Haskell's great, but Clojure's similarly lazy in all the ways that matter, and is more practical for day-to-day use.",+ "to_user": "xshay",+ "to_user_id": 371289,+ "to_user_id_str": "371289"+ },+ {+ "created_at": "Tue, 25 Jan 2011 21:58:29 +0000",+ "from_user": "xshay",+ "from_user_id": 371289,+ "from_user_id_str": "371289",+ "geo": null,+ "id": 30021714444292096,+ "id_str": "30021714444292096",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1113482439/me-brisbane_normal.jpg",+ "source": "<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12" rel="nofollow">Twitter for Mac</a>",+ "text": "Just made a lazy sequence of prime numbers in haskell. I'm smitten.",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 21:48:40 +0000",+ "from_user": "stackfeed",+ "from_user_id": 199453873,+ "from_user_id_str": "199453873",+ "geo": null,+ "id": 30019243982454784,+ "id_str": "30019243982454784",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/a/1294785484/images/default_profile_3_normal.png",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "Practical Scala reference manual, for searching things like method names: Hello, \n\nInspired by\nHaskell API Searc... http://bit.ly/g4zWZQ",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 21:45:32 +0000",+ "from_user": "aapnoot",+ "from_user_id": 17489366,+ "from_user_id_str": "17489366",+ "geo": null,+ "id": 30018455189065728,+ "id_str": "30018455189065728",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "download 0.3.1, added by MagnusTherning: High-level file download based on URLs http://bit.ly/i8mYvi",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 21:45:31 +0000",+ "from_user": "aapnoot",+ "from_user_id": 17489366,+ "from_user_id_str": "17489366",+ "geo": null,+ "id": 30018452601180160,+ "id_str": "30018452601180160",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a3.twimg.com/sticky/default_profile_images/default_profile_2_normal.png",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "download 0.3.1.1, added by MagnusTherning: High-level file download based on URLs http://bit.ly/eHfiJB",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 21:45:31 +0000",+ "from_user": "Hackage",+ "from_user_id": 17671137,+ "from_user_id_str": "17671137",+ "geo": null,+ "id": 30018451867176960,+ "id_str": "30018451867176960",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/290264834/Haskell-logo-outer-glow_normal.png",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "download 0.3.1, added by MagnusTherning: High-level file download based on URLs http://bit.ly/i8mYvi",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 21:45:04 +0000",+ "from_user": "newsyc100",+ "from_user_id": 138502705,+ "from_user_id_str": "138502705",+ "geo": null,+ "id": 30018340839755777,+ "id_str": "30018340839755777",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/profile_images/1083845614/yclogo_normal.gif",+ "source": "<a href="http://news.ycombinator.com" rel="nofollow">newsyc</a>",+ "text": "Haskell improves log processing 4x over Python http://devblog.bu.mp/haskell-at-bump (http://bit.ly/gQxxR8)",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 21:43:32 +0000",+ "from_user": "magthe",+ "from_user_id": 1578246,+ "from_user_id_str": "1578246",+ "geo": null,+ "id": 30017953801969665,+ "id_str": "30017953801969665",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a0.twimg.com/profile_images/59312315/avatar_simpson_small_normal.jpg",+ "source": "<a href="http://api.supertweet.net" rel="nofollow">MyAuth API Proxy</a>",+ "text": "New version of download uploaded to #hackage #haskell",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 21:37:51 +0000",+ "from_user": "reward999",+ "from_user_id": 135838970,+ "from_user_id_str": "135838970",+ "geo": null,+ "id": 30016525180084224,+ "id_str": "30016525180084224",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1079929891/logo_normal.png",+ "source": "<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",+ "text": "Found Great Dane (Main & Haskell- Dallas): We found a great dane. 214-712-0000 http://bit.ly/fQ8iBw",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 21:34:22 +0000",+ "from_user": "WeiMatas",+ "from_user_id": 137719265,+ "from_user_id_str": "137719265",+ "geo": null,+ "id": 30015646020411392,+ "id_str": "30015646020411392",+ "iso_language_code": "en",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a2.twimg.com/profile_images/1092224079/8__4__normal.jpg",+ "source": "<a href="http://dlvr.it" rel="nofollow">dlvr.it</a>",+ "text": "Fourth day Rez party Eddie Haskell County in second life \u2013 which took place in cabaret Tadd",+ "to_user_id": null,+ "to_user_id_str": null+ },+ {+ "created_at": "Tue, 25 Jan 2011 21:33:21 +0000",+ "from_user": "listwarenet",+ "from_user_id": 144546280,+ "from_user_id_str": "144546280",+ "geo": null,+ "id": 30015392571195392,+ "id_str": "30015392571195392",+ "iso_language_code": "no",+ "metadata": {+ "result_type": "recent"+ },+ "profile_image_url": "http://a1.twimg.com/a/1295051201/images/default_profile_1_normal.png",+ "source": "<a href="http://1e10.org/cloud/" rel="nofollow">1e10</a>",+ "text": "http://www.listware.net/201101/haskell-cafe/83889-haskell-cafe-gpl-license-of-h-matrix-and-prelude-numeric.html Haskell-cafe -",+ "to_user_id": null,+ "to_user_id_str": null+ }+ ],+ "results_per_page": 100,+ "since_id": 0,+ "since_id_str": "0"+ }+ |]+
+ json-syntax.cabal view
@@ -0,0 +1,89 @@+cabal-version: 2.2+name: json-syntax+version: 0.1.0.0+synopsis: High-performance JSON parser+description:+ This library parses JSON into a @Value@ type that is consistent with the+ ABNF described in [RFC 7159](https://tools.ietf.org/html/rfc7159). The+ parser is about six times faster than the parser that `aeson` provides.+ This parser is however, non-resumable, so if resumable parsing is+ important, `aeson` should be preferred.+ .+ This library does not include any functions or typeclasses to help users+ marshal `Value` to their application-specific data types. Such functions+ and typeclasses are outside the scope of this library. If anyone writes a+ library that offers users these conveniences open a issue so that the+ @json-syntax@ documentation can point users to it.+homepage: https://github.com/andrewthad/json-syntax+bug-reports: https://github.com/andrewthad/json-syntax/issues+license: BSD-3-Clause+license-file: LICENSE+author: Andrew Martin+maintainer: andrew.thaddeus@gmail.com+copyright: 2019 Andrew Martin+category: Data+build-type: Simple+extra-source-files: CHANGELOG.md++library+ exposed-modules: Json+ build-depends:+ , array-builder >=0.1 && <0.2+ , array-chunks >=0.1.1 && <0.2+ , base >=4.12 && <5+ , bytesmith >=0.3.2 && <0.4+ , byteslice >=0.1.3 && <0.3+ , scientific-notation >=0.1.1 && <0.2+ , text-short >=0.1.3 && <0.2+ , primitive >=0.7 && <0.8+ , bytestring >=0.10.8 && <0.11+ hs-source-dirs: src+ default-language: Haskell2010+ ghc-options: -Wall -O2++test-suite test+ default-language: Haskell2010+ type: exitcode-stdio-1.0+ hs-source-dirs: test, common+ main-is: Main.hs+ other-modules:+ Twitter100+ ghc-options: -Wall -O2+ build-depends:+ , aeson+ , array-chunks+ , base >=4.12.0.0 && <5+ , byteslice >=0.1.3+ , bytestring+ , json-syntax+ , neat-interpolation >=0.3.2+ , primitive+ , scientific+ , scientific-notation >=0.1.1+ , small-bytearray-builder+ , tasty >=1.2.3 && <1.3+ , tasty-hunit >=0.10.0.2 && <0.11+ , text >=1.2+ , text-short+ , unordered-containers+ , vector++benchmark bench+ type: exitcode-stdio-1.0+ build-depends:+ , aeson+ , base+ , byteslice+ , bytestring+ , gauge+ , json-syntax+ , neat-interpolation >=0.3.2+ , primitive+ , text >=1.2+ , scientific-notation >=0.1.1+ ghc-options: -Wall -O2+ default-language: Haskell2010+ hs-source-dirs: bench, common+ main-is: Main.hs+ other-modules:+ Twitter100
+ src/Json.hs view
@@ -0,0 +1,344 @@+{-# language BangPatterns #-}+{-# language BinaryLiterals #-}+{-# language BlockArguments #-}+{-# language DerivingStrategies #-}+{-# language DeriveAnyClass #-}+{-# language LambdaCase #-}+{-# language MagicHash #-}+{-# language TypeApplications #-}++module Json+ ( -- * Types+ Value(..)+ , Member(..)+ , SyntaxException(..)+ -- * Functions+ , decode+ ) where++import Prelude hiding (Bool(True,False))++import Control.Exception (Exception)+import Control.Monad.ST (ST)+import Data.Bits ((.&.),(.|.),unsafeShiftR)+import Data.Builder.ST (Builder)+import Data.Bytes.Parser (Parser)+import Data.Bytes.Types (Bytes(..))+import Data.Char (ord)+import Data.Chunks (Chunks(ChunksNil))+import Data.Number.Scientific (Scientific)+import Data.Primitive (ByteArray,MutableByteArray)+import Data.Text.Short (ShortText)+import GHC.Exts (Char(C#),Int(I#),gtWord#,ltWord#,word2Int#,chr#)+import GHC.Word (Word8(W8#),Word16(W16#))++import qualified Prelude+import qualified Data.Builder.ST as B+import qualified Data.Bytes.Parser as P+import qualified Data.Text.Short.Unsafe as TS+import qualified Data.Number.Scientific as SCI+import qualified Data.Primitive as PM+import qualified Data.Bytes.Parser.Utf8 as Utf8+import qualified Data.Bytes.Parser.Latin as Latin+import qualified Data.ByteString.Short.Internal as BSS+import qualified Data.Bytes.Parser.Unsafe as Unsafe++-- | The JSON syntax tree described by the ABNF in RFC 7159. Notable+-- design decisions include:+--+-- * @True@ and @False@ are their own data constructors rather than+-- being lumped together under a data constructor for boolean values.+-- This improves performance when decoding the syntax tree to a @Bool@.+-- * @Object@ uses an association list rather than a hash map. This is+-- the data type that key-value pairs can be parsed into most cheaply.+-- * @Object@ and @Array@ both use 'Chunks' rather than using @SmallArray@+-- or cons-list directly. This a middle ground between those two types. We+-- get the efficent use of cache lines that @SmallArray@ offers, and we get+-- the worst-case @O(1)@ appends that cons-list offers. Users will typically+-- fold over the elements with the @Foldable@ instance of 'Chunks', although+-- there are functions in @Data.Chunks@ that efficently perform other+-- operations.+data Value+ = Object !(Chunks Member)+ | Array !(Chunks Value)+ | String {-# UNPACK #-} !ShortText+ | Number {-# UNPACK #-} !Scientific+ | Null+ | True+ | False+ deriving stock (Eq,Show)++-- | Exceptions that can happen while parsing JSON. Do not pattern+-- match on values of this type. New data constructors may be added+-- at any time without a major version bump.+data SyntaxException+ = EmptyInput+ | ExpectedColon+ | ExpectedCommaOrRightBracket+ | ExpectedFalse+ | ExpectedNull+ | ExpectedQuote+ | ExpectedQuoteOrRightBrace+ | ExpectedTrue+ | IncompleteArray+ | IncompleteEscapeSequence+ | IncompleteObject+ | IncompleteString+ | InvalidEscapeSequence+ | InvalidLeader+ | InvalidNumber+ | LeadingZero+ | UnexpectedLeftovers+ deriving stock (Eq,Show)+ deriving anyclass (Exception)++-- | A key-value pair in a JSON object. The name of this type is+-- taken from section 4 of RFC 7159.+data Member = Member+ { key :: {-# UNPACK #-} !ShortText+ , value :: !Value+ } deriving stock (Eq,Show)++emptyArrayValue :: Value+{-# noinline emptyArrayValue #-}+emptyArrayValue = Array ChunksNil++emptyObjectValue :: Value+{-# noinline emptyObjectValue #-}+emptyObjectValue = Object ChunksNil++isSpace :: Word8 -> Prelude.Bool+isSpace w =+ w == c2w ' '+ || w == c2w '\t'+ || w == c2w '\r'+ || w == c2w '\n'++-- | Decode a JSON syntax tree from a byte sequence.+decode :: Bytes -> Either SyntaxException Value+decode = P.parseBytesEither do+ P.skipWhile isSpace+ result <- Latin.any EmptyInput >>= parser+ P.skipWhile isSpace+ P.endOfInput UnexpectedLeftovers+ pure result++-- Precondition: skip over all space before calling this.+-- It will not skip leading space for you. It does+parser :: Char -> Parser SyntaxException s Value+parser = \case+ '{' -> objectTrailedByBrace+ '[' -> arrayTrailedByBracket+ 't' -> do+ Latin.char3 ExpectedTrue 'r' 'u' 'e'+ pure True+ 'f' -> do+ Latin.char4 ExpectedFalse 'a' 'l' 's' 'e'+ pure False+ 'n' -> do+ Latin.char3 ExpectedNull 'u' 'l' 'l'+ pure Null+ '"' -> do+ start <- Unsafe.cursor+ string String start+ '-' -> fmap Number (SCI.parserNegatedUtf8Bytes InvalidNumber)+ '0' -> Latin.trySatisfy (\c -> c >= '0' && c <= '9') >>= \case+ Prelude.True -> P.fail LeadingZero+ Prelude.False -> fmap Number (SCI.parserTrailingUtf8Bytes InvalidNumber 0)+ c | c >= '1' && c <= '9' ->+ fmap Number (SCI.parserTrailingUtf8Bytes InvalidNumber (ord c - 48))+ _ -> P.fail InvalidLeader++objectTrailedByBrace :: Parser SyntaxException s Value+objectTrailedByBrace = do+ P.skipWhile isSpace+ Latin.any IncompleteObject >>= \case+ '}' -> pure emptyObjectValue+ '"' -> do+ start <- Unsafe.cursor+ !theKey <- string id start+ P.skipWhile isSpace+ Latin.char ExpectedColon ':'+ P.skipWhile isSpace+ val <- Latin.any IncompleteObject >>= parser+ let !mbr = Member theKey val+ !b0 <- P.effect B.new+ b1 <- P.effect (B.push mbr b0)+ objectStep b1+ _ -> P.fail ExpectedQuoteOrRightBrace++objectStep :: Builder s Member -> Parser SyntaxException s Value+objectStep !b = do+ P.skipWhile isSpace+ Latin.any IncompleteObject >>= \case+ ',' -> do+ P.skipWhile isSpace+ Latin.char ExpectedQuote '"'+ start <- Unsafe.cursor+ !theKey <- string id start+ P.skipWhile isSpace+ Latin.char ExpectedColon ':'+ P.skipWhile isSpace+ val <- Latin.any IncompleteObject >>= parser+ let !mbr = Member theKey val+ P.effect (B.push mbr b) >>= objectStep+ '}' -> do+ !r <- P.effect (B.freeze b)+ pure (Object r)+ _ -> P.fail ExpectedCommaOrRightBracket++-- This eats all the space at the front of the input. There+-- is no need to skip over it before calling this function.+-- RFC 7159 defines array as:+--+-- > begin-array = ws LBRACKET ws+-- > array = begin-array [ value *( value-separator value ) ] end-array+--+-- This parser handles everything after the LBRACKET character.+arrayTrailedByBracket :: Parser SyntaxException s Value+arrayTrailedByBracket = do+ P.skipWhile isSpace+ Latin.any IncompleteArray >>= \case+ ']' -> pure emptyArrayValue+ c -> do+ !b0 <- P.effect B.new+ val <- parser c+ b1 <- P.effect (B.push val b0)+ arrayStep b1++-- From RFC 7159:+--+-- > value-separator = ws COMMA ws +-- > array = begin-array [ value *( value-separator value ) ] end-array+--+-- This handles the all values after the first one. That is:+--+-- > *( value-separator value )+arrayStep :: Builder s Value -> Parser SyntaxException s Value+arrayStep !b = do+ P.skipWhile isSpace+ Latin.any IncompleteArray >>= \case+ ',' -> do+ P.skipWhile isSpace+ val <- Latin.any IncompleteArray >>= parser+ P.effect (B.push val b) >>= arrayStep+ ']' -> do+ !r <- P.effect (B.freeze b)+ pure (Array r)+ _ -> P.fail ExpectedCommaOrRightBracket++c2w :: Char -> Word8+c2w = fromIntegral . ord++-- This is adapted from the function bearing the same name+-- in json-tokens. If you find a problem with it, then+-- something if wrong in json-tokens as well.+--+-- TODO: Quit doing this CPS and inline nonsense. We should+-- be able to unbox the resulting ShortText as ByteArray# and+-- mark the function as NOINLINE. This would prevent the generated+-- code from being needlessly duplicated in three different places.+string :: (ShortText -> a) -> Int -> Parser SyntaxException s a+{-# inline string #-}+string wrap !start = go 1 where+ go !canMemcpy = do+ P.any IncompleteString >>= \case+ 92 -> P.any InvalidEscapeSequence *> go 0 -- backslash+ 34 -> do -- double quote+ !pos <- Unsafe.cursor+ case canMemcpy of+ 1 -> do+ src <- Unsafe.expose+ str <- P.effect $ do+ let end = pos - 1+ let len = end - start+ dst <- PM.newByteArray len+ PM.copyByteArray dst 0 src start len+ PM.unsafeFreezeByteArray dst+ pure (wrap (TS.fromShortByteStringUnsafe (byteArrayToShortByteString str)))+ _ -> do+ Unsafe.unconsume (pos - start)+ let end = pos - 1+ let maxLen = end - start+ copyAndEscape wrap maxLen+ W8# w -> go (canMemcpy .&. I# (ltWord# w 128##) .&. I# (gtWord# w 31##))++copyAndEscape :: (ShortText -> a) -> Int -> Parser SyntaxException s a+{-# inline copyAndEscape #-}+copyAndEscape wrap !maxLen = do+ !dst <- P.effect (PM.newByteArray maxLen)+ let go !ix = Utf8.any# IncompleteString `P.bindFromCharToLifted` \c -> case c of+ '\\'# -> Latin.any IncompleteEscapeSequence >>= \case+ '"' -> do+ P.effect (PM.writeByteArray dst ix (c2w '"'))+ go (ix + 1)+ '\\' -> do+ P.effect (PM.writeByteArray dst ix (c2w '\\'))+ go (ix + 1)+ 't' -> do+ P.effect (PM.writeByteArray dst ix (c2w '\t'))+ go (ix + 1)+ 'n' -> do+ P.effect (PM.writeByteArray dst ix (c2w '\n'))+ go (ix + 1)+ 'r' -> do+ P.effect (PM.writeByteArray dst ix (c2w '\r'))+ go (ix + 1)+ '/' -> do+ P.effect (PM.writeByteArray dst ix (c2w '/'))+ go (ix + 1)+ 'b' -> do+ P.effect (PM.writeByteArray dst ix (c2w '\b'))+ go (ix + 1)+ 'f' -> do+ P.effect (PM.writeByteArray dst ix (c2w '\f'))+ go (ix + 1)+ 'u' -> do+ w <- Latin.hexFixedWord16 InvalidEscapeSequence+ if w >= 0xD800 && w < 0xDFFF+ then go =<< P.effect (encodeUtf8Char dst ix '\xFFFD')+ else go =<< P.effect (encodeUtf8Char dst ix (w16ToChar w))+ _ -> P.fail InvalidEscapeSequence+ '"'# -> do+ str <- P.effect+ (PM.unsafeFreezeByteArray =<< PM.resizeMutableByteArray dst ix)+ pure (wrap (TS.fromShortByteStringUnsafe (byteArrayToShortByteString str)))+ _ -> go =<< P.effect (encodeUtf8Char dst ix (C# c))+ go 0++encodeUtf8Char :: MutableByteArray s -> Int -> Char -> ST s Int+encodeUtf8Char !marr !ix !c+ | c < '\128' = do+ PM.writeByteArray marr ix (c2w c)+ pure (ix + 1)+ | c < '\x0800' = do+ PM.writeByteArray marr ix+ (fromIntegral @Int @Word8 (unsafeShiftR (ord c) 6 .|. 0b11000000))+ PM.writeByteArray marr (ix + 1)+ (0b10000000 .|. (0b00111111 .&. (fromIntegral @Int @Word8 (ord c))))+ pure (ix + 2)+ | c <= '\xffff' = do+ PM.writeByteArray marr ix+ (fromIntegral @Int @Word8 (unsafeShiftR (ord c) 12 .|. 0b11100000))+ PM.writeByteArray marr (ix + 1)+ (0b10000000 .|. (0b00111111 .&. (fromIntegral @Int @Word8 (unsafeShiftR (ord c) 6))))+ PM.writeByteArray marr (ix + 2)+ (0b10000000 .|. (0b00111111 .&. (fromIntegral @Int @Word8 (ord c))))+ pure (ix + 3)+ | otherwise = do+ PM.writeByteArray marr ix+ (fromIntegral @Int @Word8 (unsafeShiftR (ord c) 18 .|. 0b11110000))+ PM.writeByteArray marr (ix + 1)+ (0b10000000 .|. (0b00111111 .&. (fromIntegral @Int @Word8 (unsafeShiftR (ord c) 12))))+ PM.writeByteArray marr (ix + 2)+ (0b10000000 .|. (0b00111111 .&. (fromIntegral @Int @Word8 (unsafeShiftR (ord c) 6))))+ PM.writeByteArray marr (ix + 3)+ (0b10000000 .|. (0b00111111 .&. (fromIntegral @Int @Word8 (ord c))))+ pure (ix + 4)++byteArrayToShortByteString :: ByteArray -> BSS.ShortByteString+byteArrayToShortByteString (PM.ByteArray x) = BSS.SBS x++-- Precondition: Not in the range [U+D800 .. U+DFFF]+w16ToChar :: Word16 -> Char+w16ToChar (W16# w) = C# (chr# (word2Int# w))
+ test/Main.hs view
@@ -0,0 +1,91 @@+{-# language LambdaCase #-}+{-# language OverloadedStrings #-}++import Data.ByteString.Short.Internal (ShortByteString(SBS))+import Data.Bytes (Bytes)+import Data.Primitive (ByteArray(ByteArray))+import Data.Scientific (Scientific,scientific)+import Data.Text.Short (ShortText)+import Test.Tasty (defaultMain,testGroup,TestTree)+import Test.Tasty.HUnit ((@=?))+import Twitter100 (encodedTwitter100,byteStringTwitter100)++import qualified Data.Aeson as AE+import qualified Data.Bytes as Bytes+import qualified Data.Chunks as Chunks+import qualified Data.HashMap.Strict as HM+import qualified Data.Number.Scientific as SCI+import qualified Data.Text.Short as TS+import qualified GHC.Exts as Exts+import qualified Json as J+import qualified Test.Tasty.HUnit as THU++main :: IO ()+main = defaultMain tests++tests :: TestTree+tests = testGroup "Tests"+ [ THU.testCase "A" $+ Right (J.Object mempty)+ @=?+ J.decode (Bytes.fromAsciiString "{}")+ , THU.testCase "B" $+ Right (J.Object (Exts.fromList [Exts.fromList [J.Member "foo" J.True]]))+ @=?+ J.decode (Bytes.fromAsciiString "{\"foo\" : true}")+ , THU.testCase "C" $+ Right (J.Array (Exts.fromList [Exts.fromList [J.String "bar"]]))+ @=?+ J.decode (Bytes.fromAsciiString "[\"bar\"]")+ , THU.testCase "D" $+ Right (J.Object (Exts.fromList [Exts.fromList [J.Member "foo" J.True, J.Member "bar" J.False]]))+ @=?+ J.decode (Bytes.fromAsciiString "{\"foo\" : true, \"bar\": false }")+ , THU.testCase "E" $+ Right (J.String "Smile: 😂")+ @=?+ J.decode (shortTextToBytes "\"Smile: 😂\"")+ , THU.testCase "F" $+ Right (J.Array (Exts.fromList [Exts.fromList [ J.Object mempty, J.Object mempty, J.Null ]]))+ @=?+ J.decode (shortTextToBytes " [ {} , { } , null ] ")+ , THU.testCase "G" $ case J.decode (shortTextToBytes " [ 55e2 , 1 ] ") of+ Right (J.Array xs) -> case Exts.toList (Chunks.concat xs) of+ [J.Number a, J.Number b] -> do+ SCI.toWord32 a @=? Just 5500+ SCI.toWord32 b @=? Just 1+ _ -> fail "no good y"+ _ -> fail "no good x"+ , THU.testCase "H" $ case J.decode (shortTextToBytes " [] x") of+ Left _ -> pure ()+ Right _ -> fail "this was not supposed parse"+ , THU.testCase "Twitter100" $+ case J.decode (Bytes.fromByteArray encodedTwitter100) of+ Left _ -> fail "nope"+ Right j -> case AE.decodeStrict byteStringTwitter100 of+ Nothing -> fail "aeson is messed up"+ Just ae -> ae @=? toAesonValue j+ + ]++toBadSci :: SCI.Scientific -> Scientific+toBadSci = SCI.withExposed+ (\a b -> scientific (fromIntegral a) b)+ (\a b -> scientific a (fromIntegral b))++toAesonValue :: J.Value -> AE.Value+toAesonValue = \case+ J.True -> AE.Bool True+ J.False -> AE.Bool False+ J.Null -> AE.Null+ J.String t -> AE.String (TS.toText t)+ J.Number n -> AE.Number (toBadSci n)+ J.Object mbrs -> AE.Object $ foldr+ (\(J.Member key val) hm -> HM.insert (TS.toText key) (toAesonValue val) hm)+ HM.empty mbrs+ J.Array vals -> AE.Array $ Exts.fromList $ foldr+ (\x xs -> toAesonValue x : xs) [] vals++shortTextToBytes :: ShortText -> Bytes+shortTextToBytes str = case TS.toShortByteString str of+ SBS x -> let y = ByteArray x in Bytes.fromByteArray y