News aggregator
happs-2012-10-08.txt
ICFP 1996: Philadelphia, Pennsylvania
hdbc-odbc not getting any data using mssql storedprocedure
Bryce Verdier: My First Yesod App
First off, I just wanted to say that I hope everyone had a relaxing and enjoyable holiday season and that you enjoyed your New Year's celebration. Whatever you did that day or night, don't name it after me.
In my last post, I showed you how to create a simple web service that responded to three different URLs and interacted with a database using Python and the Flask framework. Now I'm going to show you how to program the same thing in Haskell using the Yesod framework. For those of you too “efficient” to look them up on the previous page HERE, I'm going to repost the requirements:
Using python with gevent 0.13.x and your choice of additional libraries and/or frameworks, implement a single HTTP server with API endpoints that provide the following functionalities:
- $ curl -s 'http://127.0.0.1:8080/fib/13'
- {"response": 233}
- $ curl -s 'http://127.0.0.1:8080/fib/12'
- {"response": 144}
- $ curl -s 'http://127.0.0.1:8080/google-body'
- {"response": "272cca559ffe719d20ac90adb9fc4e5716479e96"}
- $ curl -d 'value=something' 'http://127.0.0.1:8080/store'
- $ curl 'http://127.0.0.1:8080/store'
- {"response": "something"}</li>
- A Fibonacci endpoint that accepts a number and returns the Fibonacci calculation for that number, and returns result in JSON format. example:
- An endpoint that fetches the Google homepage and returns the sha1 of the response message-body (HTTP body data).example:
-
Using some external storage of your choice (can be redis, memcache, sqlite, mysql, etc), provide a means to store and then retrieve a value.Example:
Like the last post, I'm going to talk about the individual functions first, then post the whole code at the end. Let's start with the first requirement, creating a good old Fibonacci sequence:
- handleFibR :: Int -> Handler RepJson
- handleFibR num = jsonToRepJson $ object ["response" .= show_fib]
- where
- show_fib = show $ fib num
- fib :: Int -> Int
- fib 0 = 0
- fib 1 = 1
- fib n = fib (n - 1) + fib (n – 2)
I'm going to go ahead and describe the code from the bottom up - it's a little weird but it's a lot easier to explain that way, trust me. The show_fib function is just a simple function to sum the values created from the Fibonacci sequence. The result of that function is used as the “value” component of a Pair type that is created with the “.=” operator and the “response” string, and is contained within a list. The object function takes a list of Pairs as its input and creates a Value type, which is described in the documentation as “A JSON value represented as a Haskell value.” This Value is then passed as the input into the jsonToRepJson function. All of these functions come together beautifully so that when you point your browser to http://localhost:3000/fib/24, you get this response:
{"response":"46368"}
For my next trick, I'm going to pull a SHA1 hash out from the Google homepage source code.
- gGoogR :: Handler RepJson$
- getGoogR = do$
- body <- try (simpleHttp "http://www.google.com”)
- case body of$
- Left (SomeException ex) -> jsonToRepJson $ object [“response” .= (“ERROR: “ ++ (show ex))]
- Right val -> jsonToRepJson $ object [“response” .= (showDigest $ sha1 val)]
Much like the last function, this function will return a Handler containing a RepJson . First I use the simpleHttp function to travel to the interwebs and pull the Google homepage. Because simpleHttp will throw an HttpException with any non 200 status code, I have the function called within a try function, putting the result into “body”. Body is of the Either type, which means it can have one of two possible values (like Schrodinger's cat). If something went wrong, the value would be in the “Left” side of the Either type. If that's what happened, I don't really care what went wrong so I just return a generic error message. If everything flowed smoothly like all code does (snicker), the data would be on the “Right” side of Either, allowing me to pull the data out using the Right function and named val. The code after this point is extremely similar to the previous example, the difference being the output. The website source code is used as input for the sha1 function, creating a Digest type, then I carry that over to showDigest, which returns a string 160 characters long. All of this is bubbled up to the handler and the user sees:
{"response":"ddd27a244477532f7be5207582afca72b9f74224"}
Your results will differ! For dealing with the database, we need functions that can handle both GET and POST requests. Before I explain those functions, I want to take a quick moment to share the database schema and the “runDB” function:
- share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist|
- Stuff
- value Text
- deriving Show
- |]
- runDB action = do
- Challenge pool <- getYesod
- runSqlPool action pool
If you are a little confused by these two things, don't fear. I will do my best to describe them in a moment. If that still doesn't help then maybe viewing the entire code base below will. The first code block above is responsible for creating the Stuff database which holds a single column, called “value”. It reminds me of user defined datatypes created with the “data” Haskell keyword.
The second block is really me cargo cult programming. I've seen this technique used in a lot of the examples of the Yesod book, so I copied it while I was writing this project. The best way I can describe it is as a wrapper function for using an item from a pool of database connectors, and using some of those connectors to to run the query.
Now that you know what the database looks like and how we access it, we can move onto the functions that interact with it. Here is the code for the POST request:
- postStoreR :: Handler ()
- postStoreR = do
- mvalue <- runInputPost $ ireq textField "value"
- runDB $ insert $ Stuff mvalue
- sendResponseStatus status200 ()
This function just returns a Handler unit. Using the ireq function, we look through the POST request for the expected input keyed as “value”. The output of that function goes through the runInputPost, and deposits the contents into mvalue. We take mvalue, change it to become a Stuff type, pass that to the insert function which, when it runs, returns an automatically created key. and then moving that along to runDB, which inserts our data into the database. The last line returns the 200 status back to the client, using the sendResponseStatus.
Finally, for the GET request we have:
- getStoreR :: Handler RepJson
- getStoreR = do
- mvalue <- runDB $ selectFirst [] [Desc StuffValue, LimitTo 1]
- case mvalue of
- Nothing -> jsonToRepJson $ object ["response" .= (show "NO DATA IN DATABASE")]
- Just mvalue' -> jsonToRepJson $ object ["response" .= (show . stuffValue $ entityVal mvalue')]
The result of the selectFirst function provides the input for runDB. The first argument for selectFirst is an empty list, this argument is for filtering on some kind of value( greater than, less than, not equal to, etc). I have left it blank because I really don't care what the value of “value” is; I just want it. The second list is telling the database to put the column values in descending order. The first line is the Haskell equivalent of the following SQL code:
SELECT * FROM Stuff GROUP BY VALUE DESC LIMIT 1;
The results of which are named mvalue. Since it's possible to have nothing in the response, I use the case statement to dig inside mvalue and look around. If “Nothing” was returned, I send back a little json blurb letting the user know that nothing was found, most likely because there isn't data in the database. If something was returned, pull that value out, and mix it all in the with json recipe you've seen me using thus far, and then send the data on its way.
As the title says, this was my first Yesod web app. I know that I have only scratched the surface of what this framework can do and I'm really interested in creating more with it. I will admit that I initially found the interaction with the database a little cumbersome when compared to Django or Flask. That doesn't mean I don't like it, it's just a little awkward when I was first trying to understand how to work with it. Once I got over those differences, I realized that it mentally translates to SQL better than the other frameworks. Again, I really like Yesod and look forward to using it in the future.
As always, I and my code welcome questions, comments, and the occasional funny and creative insult.
- {-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell #-}
- {-# LANGUAGE GADTs,OverloadedStrings,FlexibleContexts, FlexibleInstances #-}
- import Yesod as Y
- import Data.Text (pack, Text)
- import Network.HTTP.Conduit (simpleHttp)
- import Network.HTTP.Types (status200)
- import Data.Digest.Pure.SHA (showDigest, sha1)
- import Database.Persist.Sqlite
- import Data.Maybe
- import Control.Exception.Lifted hiding (Handler)
- import Data.ByteString.Lazy.Internal (ByteString)
- share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist|
- Stuff
- value Text
- deriving Show
- |]
- data Challenge = Challenge ConnectionPool
- mkYesod "Challenge" [parseRoutes|
- /fib/#Int FibR
- /google-body GoogR GET
- /store StoreR POST GET
- |]
- instance Yesod Challenge
- instance RenderMessage Challenge FormMessage where
- renderMessage _ _ = defaultFormMessage
- instance YesodPersist Challenge where
- type YesodPersistBackend Challenge = SqlPersist
- runDB action = do
- Challenge pool <- getYesod
- runSqlPool action pool
- handleFibR :: Int -> Handler RepJson
- handleFibR num = jsonToRepJson $ object ["response" .= show_fib]
- where
- show_fib = show $ fib num
- fib :: Int -> Int
- fib 0 = 0
- fib 1 = 1
- fib n = fib (n - 1) + fib (n - 2)
- getGoogR :: Handler RepJson
- getGoogR = do
- body <- try (simpleHttp "http://www.google.com")
- case body of
- Left (SomeException ex) -> jsonToRepJson $ object ["response" .= ("ERROR: " ++ (show ex))]
- Right val -> jsonToRepJson $ object ["response" .= (showDigest $ sha1 val)]
- postStoreR :: Handler ()
- postStoreR = do
- mvalue <- runInputPost $ ireq textField "value"
- runDB $ Y.insert $ Stuff mvalue
- sendResponseStatus status200 ()
- getStoreR :: Handler RepJson
- getStoreR = do
- mvalue <- runDB $ Y.selectFirst [] [Y.Desc StuffValue, Y.LimitTo 1]
- case mvalue of
- Nothing -> jsonToRepJson $ object ["response" .= (show "NO DATA IN DATABASE")]
- Just mvalue' -> jsonToRepJson $ object ["response" .= (show . stuffValue $ Y.entityVal mvalue')]
- main = withSqlitePool ":memory:" 10 $ \pool -> do
- runSqlPool (runMigration migrateAll) pool
- warpDebug 3000 $ Challenge pool
Learn You a Haskell for Great Good!
Success story: novice haskeller moves console cursor with “netwire” FRP library « UProLa
Metaprogramming in Haskell?
I'm looking for resources on metaprogramming in Haskell that can explain how it is done to someone that knows nothing about the language. I've found a few resources, but they all assume prior knowledge/experience with the language.
I know this sounds like I'm jumping the gun, but my entire experience with programming has been with functional languages...specifically R, Scheme, and Clojure. In my opinion, a language isn't worth taking the time to learn unless it is adept and agile in metaprogramming. After learning Clojure and Scheme, it seems like every other language I have found that supports metaprogramming is needlessly complex for anything non-trivial (for example, Ruby and its Procs).
Does anybody know of some resources that can explain this to a Haskell newb?
submitted by saosebastiao[link] [59 comments]
Yet another Conduit question
Announcement - Haskell User Group Frankfurt
why GHC cannot infer type in this case?
FP Complete: School of Haskell Goes Beta
We are happy to announce the beta of the FP Complete School of Haskell. Our goal is to remove the biggest obstacle to learning the language.
All you procrastinators promising yourselves to take up Haskell one day — you have no excuses left! Go to our beta signup page and get a chance to experience Haskell the way it was intended to be. You can also watch a video walk-through of the School of Haskell on that page.
What is School of Haskell?School of Haskell is mainly about learning Haskell. In this world of instant gratification, to ask a potential student to find a book (even if it’s an online book), install the compiler, fiddle with the editor, go through the edit/save/load/compile/fix-errors/eventually-run cycle is just too much to ask. This is the 21st century! Granted, we are still far away from The Diamond Age, and the School of Haskell is not “A Young Lady’s Illustrated Primer,” but we are getting there.
The first thing you notice when you browse through the School of Haskell is a number of tutorials, some of them bundled into courses. At this moment the list is very incomplete, but it’s enough to get you started. More content will be appearing on a regular basis.
When you open a tutorial, it looks pretty much like a programmer’s blog — until you notice that some of the embedded code fragments are alive. You can compile and run them with one press of a button.
Some of the snippets are interactive: you are prompted for input and the result is evaluated and displayed. Others create mini web sites with all the richness of HTML 5.
But the real fun begins when you discover that you can edit these fragments in place. There are exercises at the end of each tutorial that you can solve right there on the spot. You can play with the snippets that generate web pages and watch the effects. You can’t get more immediate than that.
Can I create my own content?Our initial goal was to just publish a few active tutorials, but it quickly became obvious that, if we wanted more content, we’d have to involve the community at large. But to make content creation attractive we had to provide tools. So we implemented an online markup editor and threw in a live preview window. One thing led to another and we ended up with a whole system that lets every user develop their own content and share it with the public. So now we have a little publishing system, which should be very attractive to Haskell programmers.
How cool is it to be able to write a post with embedded runnable and editable Haskell programs? We have already seen very enthusiastic response from our alpha users who immediately started producing amazing content. Some of them decided to move their blogs to the new medium that the School of Haskell offers.
But you don’t have to be an experienced Haskell programmer to take advantage or our content creation system. It so happens that the content editor can be easily used as an interactive scratchpad where you can create, compile, and run small Haskell programs. Just surround your code with markdown fences, as in:
``` active haskell main = putStrLn "Hello Monadic World!" ```and try running it in the preview pane. We have a full blown Haskell IDE in the works, but this simple scratchpad functionality can liberate many a Haskell newcomer from the drudge of installing the compiler and libraries on their machines.
There is a fairly substantial set of libraries at your disposal when developing contents. They come from the Stackage project. We provide complete Haddock documentation and Hoogle search for those libraries (we are working on providing better UI for those!).
How is it implemented?We wouldn’t have the right to call ourselves a Haskell company if we used anything other than Haskell to implement our software. So everything above the level of Linux and AWS is written in Haskell; and that extends to large parts of the web client written in Fay — a subset of Haskell that compiles down to JavaScript. And, frankly, I can’t imagine accomplishing so much in such a short time with such a small team if we didn’t use Haskell and Haskell libraries.
In particular Michael Snoyman’s Haskell web framework Yesod was perfect for building a highly interactive modern web site sitting on top of a database and AWS cloud services, smoothly interacting with git and the GHC compiler. (It doesn’t hurt that Michael is our development lead.)
Naturally, we had to create some Yesod tutorials for the School of Haskell. But Yesod is used to implement web sites — servers that serve HTML pages over HTTP. So how do we embed live Yesod code in a tutorial? First we have to send the code to our cloud, compile and run it. The resulting web server has to listen to a port, which we provide, and send HTTP responses out to the Internet. Since this server is to be accessed over the Internet, we have to generate a temporary URL for it. In the meanwhile, client code opens a little browser within a browser and displays it in an iFrame. It then sends a request to the above mentioned web server using the temporary URL, receives the page back, and displays it.
ConclusionsWe believe that Haskell is the future of programming and that education is the first step on the path to its widespread industry adoption. To this end we have created a one-stop learning facility for both newcomers and seasoned Haskellers. We really hope that you will enjoy interacting with the School of Haskell and help it grow as a resource for the whole programming community.
AcknowledgmentNone of this would have been possible without the Haskell community and the ecosystem of compilers, libraries, packages, and tools that have been developed over decades.
Joachim Breitner: Going to FOSDEM after all
Earlier this week, things were looking different, and I did have to cancel a Haskell talk in Freiburg on Monday due to illness. But I’m back on track and will be travelling to Brussels tomorrow.
I’ll be holding a talk on how we package Haskell in Debian, on Suday at 15:30. I hope it will be useful to Debian users (who will better understand the packaging), other Debian Developers (who’ll learn about the peculiarities of Haskell and the implications for the Debian infrastructure), other distro’s maintainers (to compare best practices) and Haskell developers (to learn about the needs and worries of downstream packages). The talk will be based on my DebConf 11 talk on the same topic. I’m also happy to answer questions about Haskell, Haskell in Debian or any other topic that you want to hear my opinion about, so just talk to me during FOSDEM.
In related news: GHC 7.6.2 was uploaded to Debian experimental the day it was released; the rebuilding of all libraries is still in progress (~370 of ~570 done).
I want to create a compiler in Haskell for a custom language, but I don't really know what I'm doing. Any tips?
For fun, as an on-going side project, I want to create a compiler for a custom language. I want to take the command-based structure and "everything semantically is a string" concept from Tcl and package it up into something more modern that targets possibly the JVM. In particular, I want this language to actually have closures (and comments that are implemented at the compiler level, not as commands within the language, leading to bizarre things like curly braces inside comments mattering).
I'm thinking of writing this in Haskell, as I once played with writing a Scheme interpreter in Haskell and found it to be remarkably pleasant.
The thing is that I don't really know what I'm doing. I "know" Haskell... but I'm no expert. I've also never written a compiler. The furthest I've gone is an interpreter for Scheme and an interpreter for a basic version of BASIC.
My question is a little open-ended, but I'm mostly looking for tips, other examples I could look at (hopefully simple ones). Where do I start? What models do I follow? This is just for fun, so it is not important that the end result is actually useful. I know this is ambitious, but it should give me a lot to think about and learn and something to do in my spare time for a long while.
submitted by siralgo[link] [20 comments]