News aggregator

Strange error with cabal install on windows:

haskell-cafe - Fri, 07/08/2016 - 9:06am
I've got an error that I don't know how to fix with cabal install. Has anyone experienced such a thing? It installs fine on ubuntu but fails to install on windows 7. It's my own package called `sharc-timbre`: ~~~ Building sharc-timbre-0.1... Preprocessing library sharc-timbre-0.1... C:\Program Files\Haskell Platform\8.0.1\bin\ghc.exe: createProcess: does not exist (No such file or directory) cabal: Leaving directory 'C:\Users\антон\AppData\Local\Temp\cabal-tmp-4484\sharc-timbre-0.1' ~~~ Thanks, Anton _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
Categories: Offsite Discussion

Brent Yorgey: Eastman maximal comma-free codes in Haskell

Planet Haskell - Thu, 07/07/2016 - 8:32pm

This past January I watched a video of Don Knuth’s most recent annual Christmas lecture. Typically his Christmas lectures have been about trees, but breaking with tradition, he gave this lecture about comma-free codes, and presented an implementation of an interesting algorithm due to Willard Eastman. Of course his implementation was written in CWEB, and during the course of the lecture he noted that his algorithm was iterative, and he didn’t know of a nice way to write it recursively (or something like that). Naturally, that sounded like a challenge, so I implemented it in Haskell, and I think it came out quite nicely. (It still uses “iteration” in the sense of the iterate function, but of course that uses recursion, so…?) Unfortunately, that was in January, it is now July, and I don’t really remember how it works. So I decided I had better write about it now, before I forget even more about how it works.

A comma-free code is a set of strings such that if you concatenate any two strings in , the result does not contain any elements of as internal substrings. The term “comma-free” refers to the fact that sequences of strings from can be unambiguously concatenated, without the need for separators like commas. Even if you start reading somewhere in the middle of a message, you can unambiguously figure out how to partition the message into codewords. For example, {bear, like} is a comma-free code, but {bear, like, earl} is not, since bearlike contains earl as a substring. A comma-free code also obviously cannot contain any periodic strings (that is, strings which consist of repeated copies of some shorter string), like abcabc, since concatenating such a string with itself produces a string containing the same string as an internal prefix.

Given a fixed alphabet and codeword length, one is naturally led to ask how large a comma-free code can possibly be. Eastman solved this problem for odd codeword lengths, by showing how to construct a maximal commafree code. To understand Eastman’s solution, consider the set of all aperiodic strings of length over an alphabet (we have already seen that periodic strings cannot be part of a comma-free code). Consider two strings equivalent if they are rotations of each other. For example, bear, earb, arbe, and rbea are all equivalent. This is an equivalence relation on strings, and so it defines a partition of into classes of equivalent strings. Note that we can never have two equivalent strings as part of the same comma-free code, since if we concatenate a string with itself, the result contains all other equivalent strings as substrings. For example, bearbear contains earb, arbe, and rbea. So at most a comma-free code could contain one string from each equivalence class.

In fact, Eastman shows that for odd there are comma-free codes that contain exactly one string from each equivalence class! What’s more, his proof is constructive: he shows how to pick a particular, canonical representative from each equivalence class such that the collection of all such canonical representatives is a comma-free code. This is what the program below does: given an odd-length string, it outputs the canonical rotation of that string which is part of a maximal comma-free code.

So, without further ado, let’s see the implementation! Again, I really don’t remember much about the details of how (much less why) this works. For that, I recommend watching Knuth’s lecture or reading the explanations in his code (you’ll probably want to compile it into LaTeX first).

First, some imports and such. Look, ma, no LANGUAGE extensions!

> module Commafree where > > import Control.Arrow (first) > import Control.Monad (when) > import Data.List (findIndex, intercalate) > import Data.List.Split > import Data.Maybe (catMaybes) > import Data.Monoid ((<>)) > > import System.Environment > import System.Exit > import Text.Printf > import Text.Read (readMaybe)

Here’s the main Eastman algorithm, which actually works for any list of things with a total order (unlike Knuth’s, which only works for lists of nonnegative integers, although that is obviously just a cosmetic difference, since any finite set with a total order is isomorphic to a set of nonnegative integers). We turn each item into a singleton “block”, then iterate the eastmanRound function, which partitions the blocks into subsequences of blocks, which we coalesce into blocks again. So each iteration makes the partition coarser, i.e. the blocks get bigger. We keep iterating until there is only one block left, which contains the rotation that we seek.

> eastman :: Ord a => [a] -> [a] > eastman > = blockContent . head . head > . dropWhile ((>1) . length) > . iterate (map mconcat . eastmanRound) > . map mkBlock

Some code for dealing with blocks. A block is just a list that keeps track of its length for efficiency. The important point about blocks is that they are ordered first by length, then lexicographically (see the Ord instance below). The Monoid instance is straightforward.

> data Block a = Block { blockLen :: !Int, blockContent :: [a] } > deriving (Show, Eq) > > instance Ord a => Ord (Block a) where > compare (Block m as) (Block n bs) > = compare m n <> compare as bs > > instance Monoid (Block a) where > mempty = Block 0 [] > mappend (Block m as) (Block n bs) = Block (m+n) (as ++ bs) > > mkBlock :: a -> Block a > mkBlock a = Block 1 [a]

One round of the algorithm works as follows: we duplicate the list, partition it after each “dip” (chop splitDip, to be explained below), possibly drop some of the leading parts and coalesce other parts based on size parity (pickOdds), and then keep only a total amount of stuff equal to the length of the original list (takeTotal). This last part with takeTotal ensures that we will end up with something which is a rotation of the original input (though partitioned). In an implementation with random-access arrays, one would just wrap the indices around using mod; in this context it’s easier to first duplicate the input list so we can deal with all rotations at once, determine which rotation we want by dropping some stuff from the beginning, then drop any excess stuff at the end.

> eastmanRound :: Ord a => [a] -> [[a]] > eastmanRound as > = takeTotal (length as) > . pickOdds > . chop splitDip > $ (as ++ as)

It’s interesting to note that in eastmanRound the type a is actually going to be instantiated with Block b for some type b. In the first round, all the blocks are singletons, so this is no different than just taking a list of b. But in subsequent rounds the distinction is nontrivial.

A “dip” is a decreasing substring followed by a single increase, for example, 976325. (Though again, remember that we are actually dealing with sequences of blocks, not integers, so a dip is essentially a sequence of blocks of decreasing length followed by a longer one, with the requisite caveat about blocks of the same length.) splitDip looks for the first place in the list that looks like and breaks the list right after it. This is used with the chop function to split the list into a sequence of dips.

> splitDip :: Ord a => [a] -> ([a],[a]) > splitDip (a:b:cs) > | a < b = ([a,b], cs) > | otherwise = first (a:) (splitDip (b:cs)) > splitDip as = (as,[])

pickOdds does something like the following: it looks for maximal sequences of dips where the first dip has odd length and the rest have even length, and merges such sequences into one long partition. It also drops everything prior to the first odd dip. Something like that at least; my memory on this is a bit fuzzy.

> pickOdds :: [[a]] -> [[a]] > pickOdds > = map concat > . dropWhile (even . length . head) > . drop 1 > . splitAtOdds > > splitAtOdds :: [[a]] -> [[[a]]] > splitAtOdds = chop $ > \(x:xs) -> let (ys,zs) = break (odd.length) xs > in (x:ys, zs)

Finally, takeTotal just takes lists until their total length matches the given total.

> takeTotal :: Int -> [[a]] -> [[a]] > takeTotal _ [] = [] > takeTotal n _ | n <= 0 = [] > takeTotal n (xs:xss) = xs : takeTotal (n - length xs) xss

And that’s it! I also put together a main which more or less emulates what Knuth’s C program does. My program and Knuth’s give the same output on every example I have tried (except that Knuth’s prints out some intermediate information about each iteration step; mine just prints the final answer).

> main :: IO () > main = do > progName <- getProgName > args <- getArgs > let n = length args > when (n < 3) $ do > printf "Usage: %s x1 x2 ... xn\n" progName > exitWith (ExitFailure 1) > when (even n) $ do > printf "The number of items, n, should be odd, not `%d'!\n" n > exitWith (ExitFailure 2) > let ns :: [Maybe Int] > ns = map readMaybe args > case findIndex (maybe True (<0) . snd) (zip [1..] ns) of > Just i -> do > printf "Argument %d should be a nonnegative integer, not `%s'!\n" > i (args !! (i-1)) > exitWith (ExitFailure 3) > Nothing -> > putStrLn . > (' ' :) . intercalate " " . map show . > eastman . catMaybes $ ns
Categories: Offsite Blogs

Call for participation: PPDP 2016

General haskell list - Thu, 07/07/2016 - 3:15pm
============================================================ CALL FOR PARTICIPATION: PPDP 2016 18th International Symposium on Principles and Practice of Declarative Programming Edinburgh, UK, September 5-7, 2016 http://ppdp16.webs.upv.es/ co-located with LOPSTR 2016 26th International Symposium on Logic-Based Program Synthesis and Transformation Edinburgh, UK, September 6-8, 2016 http://www.cliplab.org/Conferences/LOPSTR16/ and SAS 2016 23rd Static Analysis Symposium Edinburgh, UK, September 8-10, 2016 http://staticanalysis.org/sas2016/ ============================================================ Registration is now open: http://conferences.inf.ed.ac.uk/ppdp-lopstr-sas-2016/ **Early registration until August 15** INVITED TALKS * Elvira Albert: Testing of Concurrent and Imperative Software using CLP * Greg Morrisett (jointly with LOPSTR'16): TBD * Francesco Logozzo (jointly with LOPSTR'16): TBD ACCEPTED PAPERS - Davide Fuscà, Stefano Germano, Jessica Zangari, Marco Anastasio
Categories: Incoming News

DEADLINE EXTENSION: 14th ACM MobiWac 2016, MALTA

General haskell list - Thu, 07/07/2016 - 2:42pm
** We apologize if you receive multiple copies of this message ** ================================================================== The 14th ACM International Symposium on Mobility Management and Wireless Access (MobiWac 2016) November 13 - 17, 2016 - Malta http://mobiwac-symposium.org/ ================================================================== The MOBIWAC series of event is intended to provide an international forum for the discussion and presentation of original ideas, recent results and achievements by researchers, students, and systems developers on issues and challenges related to mobility management and wireless access protocols. To keep up with the technological developments, we also open up new areas such as mobile cloud computing starting from this year. Authors are encouraged to submit both theoretical and practical results of significance on all aspects of wire
Categories: Incoming News

[ANN] processing-for-haskell. New graphics andanimation package

haskell-cafe - Wed, 07/06/2016 - 11:22am
I'd like to announce a graphics libary processing-for-haskell (available on Hackage). It tries to implement Processing language with Haskell. Processing is an imperative DSL for graphics and animation. It's very easy and fun to use. Intended to be used by non-programmers it has very small but powerful core of functions. It's a shallow EDSL. The Processing is implemented with OpenGL and GLUT. That gives us an opportunity to use all Haskell IO-functions inside the animation loop. Enjoy! github: https://github.com/anton-k/processing-for-haskell hackage: http://hackage.haskell.org/package/processing-for-haskell _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
Categories: Offsite Discussion

Space-leak incurred by constraints

glasgow-user - Wed, 07/06/2016 - 9:08am
Hi, The following reduced test-case: > {-# LANGUAGE DataKinds, TypeOperators, TypeFamilies, ConstraintKinds, > FlexibleContexts, BangPatterns #-} > module ConstraintLeak where > > import GHC.TypeLits > import Data.Proxy > > type Constraint1 n > = ( Constraint2 n > , Constraint2 (2^n) > ) > type Constraint2 n > = ( KnownNat n > , ((n-1)+1) ~ n -- Comment this line to run in constant space > ) > > test :: Constraint1 x => Proxy x -> String > test !s | s == s = test s > > main :: IO () > main = putStr (test (Proxy :: Proxy 3)) contains a space-leak when compiled without optimisations (i.e. -O0 or in GHCi). It's true that the code doesn't actually do anything (when compiled with -O you get "Exception <<loop>>"), but I'm using it to exemplify some code that runs for some time, and then prints something. As you can see, 'test' is strict in its arguments, but it seems lazy in its constraints. When I look at the heap profile (-hy), I see it ra
Categories: Offsite Discussion

Haskell Data Structure design

haskell-cafe - Wed, 07/06/2016 - 2:26am
Hello All, I am just getting myself to code in Haskell and would like to design advice. Below, I have a made up example: data ClassRoom = ClassRoom { classRoomNo:: Integer, extra_fees::Float, students: Map StudentId Student} data Student = Student {name::String, feesOwed::Float} data StudentId = Integer get_fees_owed classroom student_id = extra_fees + feesOwed $ (students classroom) M.! studentid Here the `get_fees_owed` needs information from the container 'classroom'. Here is my question/problem: I believe I should model most of my code as expressions, rather than storing pre-computed values such as `fees_owed`. But, defining expressions involve passing the container objects all over. For example, deep down in a function that deals with just one `student`, I might need the fees owed information. Without, having a reference to the container, I cannot call get_fees_owed. Also, I think it hinders composing of functions that just deal with one student at a time, but end up with some dependen
Categories: Offsite Discussion

Yesod Web Framework: Implementing HTTP/2 server push

Planet Haskell - Wed, 07/06/2016 - 1:10am
What is HTTP/2 server push?

Server push is a hot topic of HTTP/2. Effective usage of server push can improve user experience. For instance, let's consider a scenario: downloading "index.html" which requires "style.css".

If a browser uses HTTP/1.1, it gets the "index.html" first, parses it, then obtains "style.css". So, two round-trip-times (RTTs) are necessary before the browser starts rendering.

On the other hand, if a browser uses HTTP/2 and the corresponding server supports server push, only one RTT is necessary. That is, when the browser send a GET request for "index.html", the server pushes "style.css" before it transfers "index.html". When the browser parses "index.html", it finds "style.css" in its local cache. Thus, it can start rendering at this timing.

APIs for server push

So, how can we implement HTTP/2 server push in Warp? Clearly, it is necessary for an application to tell Warp what files should be pushed. One way is to extend the Response type to store information on server push. But this breaks compatibility. We need to modify all existing applications.

To keep all existing types as is, I decided to use vault in the Request type. Vault is a heterogeneous infinite map which can store any type. Warp creates a new IORef and store its getter and setter to the vault:

getHTTP2Data :: Request -> IO (Maybe HTTP2Data) setHTTP2Data :: Request -> Maybe HTTP2Data -> IO ()

HTTP2Data is the data type to store a list of files to be pushed. An application can set files to be pushed by setHTTP2Data. Warp retrieves them by getHTTP2Data and pushes them before sending the corresponding Response.

Note that the vault is a part of Web Application Interface (WAI) but these two functions are not. They are APIs provided only by Warp.

Middleware for server push

The next question is how an application knows which files to be pushed for a given URL. One way is manifest files.

Another way is learning based on Referer:. This idea came from Jetty. Typically, there is the Referer: whose value is, say, https://example.com/index.html", in a GET request to "style.css". So, analyzing requests for a while, we can learn that "style.css" should be pushed when "index.html" is requested.

@davean suggested that I implement this mechanism as a middleware. So, I created a middleware for HTTP/2 server push based on Referer:. Its default behavior for a given Request and Response is as follows:

  • If files to be pushed are found for a given path in a learning dictionary, set them by setHTTP2Data.
  • Otherwise, register the file of Response to the learning dictionary only when the following conditions are met:
  1. The Request stores a valid Referer:
  2. The Response is a file type
  3. The path of Referer: is "/" or ends with ".html"/".html"
  4. The path ends with ".js" and ".css"

The learning dictionary is cleared every 30 seconds.

Warp v3.2.7 with the push APIs and wai-http2-extra v0.0.0 with the middleware are already on Hackage. If you implement a server push middleware based on manifest files, please send a pull request on github.

Visualization

Here are screen shots of Firefox accessing the new Warp. The first figure is the first access and the middleware has not learned anything. So, no pushes are used.

The second figure is the second access. You can see .js and .css files are pushed since bullets are not green.

Next Step

The next step would be an implementation of Cache Digests for HTTP/2. In this scheme, a browser can tell a list of cached file to a server. So, the server can avoid unnecessary pushes.

Acknowledgment

Efforts to bring HTTP/2 server push feature to Warp was originally made by Andrew Pritchard. Without his experience and suggestions, this work would be impossible. I thank him deeply.

Categories: Offsite Blogs

Haskell in Leipzig 2016: Another Call for Papers(deadline extended)

haskell-cafe - Tue, 07/05/2016 - 6:39pm
                             Haskell in Leipzig                             September 14-15, 2016                             HTKW Leipzig, Germany                          http://hal2016.haskell.org/ We have received good and interesting proposals, but our schedule still has room for more. So whether you wanted to submit, but just did not make the first deadline, or whether you only now decide to come to Leipzig, this is your chance: Please submit your short abstract until Friday, July 15th. Do you need ideas? Here some possible directions:  * Very fancy type tricks using all  of GHC’s extensions.  * Very fancy type tricks using none of GHC’s extensions.  * Getting Haskell to run really really fast.  * Using Haskell to make real money, in real life.  * Showing how this one odd Haskell library make doing something    appear rally simple.  * Stuff that is really horrible with Haskell (and how to do
Categories: Offsite Discussion

The haskell-lang.org team: New haskell-lang.org

Planet Haskell - Tue, 07/05/2016 - 6:00pm

By the haskell-lang.org team: Chris Done, Chris Allen, Julie Moronuki, Michael Snoyman, Sibi Prabakaran, Gabriel Gonzalez

We are happy to announce the launch of a new Haskell community nexus site: http://haskell-lang.org/. This website is aimed at providing modern best practices information for the Haskell programming language, and in particular with providing the best possible new user experience. The aim is to lower the barrier to getting started with Haskell, and ultimately increase adoption of Haskell in the greater programming community.

The launch of this website is paired with the launch of a number of additional community resources to aid its growth:

These community resources are open to all to discuss the contents of the website, and more broadly how to make Haskell as welcoming a language, community, and ecosystem as can be managed. We encourage all Haskellers to join, and to take part in lively discussions of how to improve the state of the art within Haskell.

As this community is just forming, now is the perfect time to get involved. Post questions and comments on Reddit, Tweet to us, send pull requests for the website, and open issues. This community will become what you put into it, so help shape it from the beginning!

Why a new site?

Since it is a common question in such statements, let us ask it directly here: why create a new website instead of working to incrementally update haskell.org? In the opinion of the team behind haskell-lang.org, the tooling story and general ecosystem infrastructure for the Haskell community has accumulated enough baggage that a clean break is the best use of everybody's time. We intend to streamline the on-boarding process for new developers, move away from infrastructure that is showing its age, and embrace newer approaches to facilitate open collaboration. Similar decisions have already been made in creating the Stack build tool and Stackage.

Categories: Offsite Blogs

Joachim Breitner: HaL deadline extended

Planet Haskell - Tue, 07/05/2016 - 11:40am

There is this long-running workshop series Haskell in Leipzig, which is a meeting of all kinds of Haskell-interested folks (beginners, experts, developers, scientists), and for year’s instance, HaL 2016, I have the honour of being the program committee chair.

The original deadline passed last week, and after looking through the submissions it became clear that although the quality was good, the quantitiy was still lacking. I therefore extended the submission deadline by two weeks, until July 15th.

So if you have something worth talking about, please do submit a proposal1 and come to Leipzig!.

Why should you submit here? Because it gives you a platform to talk about your ideas to an audience that usually does not consist just of your fellow speakers, as it is often with purely academic workshops, but “real” listeners of various kinds. And it is a fun event.

And why should you come to Leipzig? Because of all the interesting talks and tutorials! Of course I cannot say a lot here yet, besides that our invited speaker Alejandro Russo from Chalmers and Gothenburg University will present his work on information-flow control in Haskell (i.e., SecLib, LIO, MAC, HLIO).

  1. And if you want to save me from sleepless nights, submit the first version a few days before the deadline…

Categories: Offsite Blogs

2nd CfP: IFL 2016 (28th Symposium on Implementation and Application of Functional Languages)

General haskell list - Tue, 07/05/2016 - 11:17am
Hello, Please, find below the second call for papers for IFL 2016. Please forward these to anyone you think may be interested. Apologies for any duplicates you may receive. best regards, Jurriaan Hage Publicity Chair of IFL --- IFL 2016 - 2nd Call for papers 28th SYMPOSIUM ON IMPLEMENTATION AND APPLICATION OF FUNCTIONAL LANGUAGES - IFL 2016 KU Leuven, Belgium In cooperation with ACM SIGPLAN August 31 - September 2, 2016 https://dtai.cs.kuleuven.be/events/ifl2016/ Scope The goal of the IFL symposia is to bring together researchers actively engaged in the implementation and application of functional and function-based programming languages. IFL 2016 will be a venue for researchers to present and discuss new ideas and concepts, work in progress, and publication-ripe results related to the implementation and application of functional languages and function-based programming. Peer-review Following the IFL tradition, IFL 2016 will use a post-symposium review pro
Categories: Incoming News

2nd CfP: IFL 2016 (28th Symposium on Implementation and Application of Functional Languages)

haskell-cafe - Tue, 07/05/2016 - 11:17am
Hello, Please, find below the second call for papers for IFL 2016. Please forward these to anyone you think may be interested. Apologies for any duplicates you may receive. best regards, Jurriaan Hage Publicity Chair of IFL --- IFL 2016 - 2nd Call for papers 28th SYMPOSIUM ON IMPLEMENTATION AND APPLICATION OF FUNCTIONAL LANGUAGES - IFL 2016 KU Leuven, Belgium In cooperation with ACM SIGPLAN August 31 - September 2, 2016 https://dtai.cs.kuleuven.be/events/ifl2016/ Scope The goal of the IFL symposia is to bring together researchers actively engaged in the implementation and application of functional and function-based programming languages. IFL 2016 will be a venue for researchers to present and discuss new ideas and concepts, work in progress, and publication-ripe results related to the implementation and application of functional languages and function-based programming. Peer-review Following the IFL tradition, IFL 2016 will use a post-symposium review pro
Categories: Offsite Discussion

[sac_svt_2017_publicity ] SAC SVT 2017 - First Call forPapers - Deadline September 15

General haskell list - Tue, 07/05/2016 - 9:10am
[Please accept our apologies for potential duplicates] ================================================== 32nd Annual ACM Symposium on Applied Computing Software Verification and Testing Track April 3 - 7, 2017, Marrakech, Morocco More information: http://http://antares.sip.ucm.es/svt2017/ <http://http//antares.sip.ucm.es/svt2017/> and http://www.sigapp.org/sac/sac2017/ <http://www.sigapp.org/sac/sac2017/> =================================================== Important dates ——————— * September 15, 2016: Papers and SRC submission * November 10, 2016: Paper and SRC notification * November 25, 2016: Camera-ready copies ACM Symposium on Applied Computing ————————————————— The ACM Symposium on Applied Computing (SAC) has gathered scientists from different areas of computing over the last thirty years. The forum represents an opportunity to interact with different communities sharing an interest in applied computing. SAC 2017 is sponsored by the ACM Special
Categories: Incoming News

Gabriel Gonzalez: Auto-generate service API endpoints from records

Planet Haskell - Tue, 07/05/2016 - 7:45am

Haskell has pretty cool support for code generation from data type definitions using GHC generics. So I thought: "why not generate a service from a data type?".

The basic idea is pretty simple. Given a data type definition like this:

data Command
= Create { filepath :: FilePath, contents :: String }
| Delete { filepath :: FilePath }

... we'll auto-generate two API endpoints:

  • /create?filepath=:string&contents=:string
  • /delete?filepath=:string

Each endpoint accepts query parameters matching the fields for their respective constructors:

$ curl 'localhost:8080/create?filepath=test.txt&contents=ABC'
"File created"
$ cat test.txt
ABC
$ curl 'localhost:8080/delete?filepath=test.txt'
"File deleted"
$ cat test.txt
cat: test.txt: No such file or directory

The complete code to build the server looks like this:

{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}

import Server.Generic
import System.Directory (removeFile)

data Command
= Create { filepath :: FilePath, contents :: String }
| Delete { filepath :: FilePath }
deriving (Generic, ParseRecord)

handler :: Command -> IO String
handler (Create file text) = do
writeFile file text
return "File created"
handler (Delete file) = do
removeFile file
return "File deleted"

main :: IO ()
main = serveJSON 8080 handler

You can test it yourself by running:

$ stack build server-generic
$ stack runghc AboveExample.hs

... and then in a separate terminal you can hit each endpoint with curl as illustrated above.

GHC Generics

The Haskell magic is in this one line of code:

deriving (Generic, ParseRecord)

This auto-generates code that tells the server how to marshal the route and query parameters into our Command data type. All we have to do is supply a handler that pattern matches on the incoming Command to decide what to do:

handler :: Command -> IO String
handler (Create file text) = do
writeFile file text
return "File created"
handler (Delete file) = do
removeFile file
return "File deleted"

You can read that as saying:

  • "If a client hits the /create endpoint, create the specified file"
  • "If a client hits the /delete endpoint, delete the specified file"

As an exercise, you can try modifying the handler to respond with the name of the file that was created or deleted.

However, you're not limited to query parameters. You can also parse data from path tokens by just omitting field labels from the data type:

{-# LANGUAGE DeriveGeneric #-}

import Server.Generic

data Command
= Add Double Double
| Multiply Double Double
deriving (Generic)

instance ParseRecord Command

handler :: Command -> IO Double
handler (Add x y) = return (x + y)
handler (Multiply x y) = return (x * y)

main :: IO ()
main = serveJSON 8080 handler

If you run the above code, you get a server that has two endpoints:

  • /add/:double/:double
  • /multiply/:double/:double

You can run the server and test that they work:

$ curl 'localhost:8080/add/2/3'
5
$ curl 'localhost:8080/multiply/2/3'
6

This library also intelligently handles optional and repeated fields in data type definitions. For example, suppose we serve this data type::

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}

import Server.Generic

data Example = Example
{ list :: [Int]
, optional :: Maybe Int
, first :: First Int
, last :: Last Int
} deriving (Generic, ParseRecord, ToJSON)

handler :: Example -> IO Example
handler = return -- Serve decoded value back to client as JSON

main :: IO ()
main = serveJSON 8080 handler

... then the server will echo back the decoded type as JSON, correctly handling absent or repeated fields:

$ curl 'localhost:8080/example'
{"list":[],"first":null,"last":null,"optional":null}
$ curl 'localhost:8080/example?optional=1&list=1&list=2&first=1&first=2&last=1&last=2'
{"list":[1,2],"first":1,"last":2,"optional":1}

Also, these repeated and optional annotations work for path components, too, in case you were wondering:

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}

import Server.Generic

data Example = Example [Int] (Maybe Text)
deriving (Generic, ParseRecord, ToJSON)

handler :: Example -> IO Example
handler = return

main :: IO ()
main = serveJSON 8080 handler

The above server does "the right thing" and doesn't need to be told where the Ints end and the Text begins:

$ curl 'localhost:8080/example'
[[],null]
$ curl 'localhost:8080/example/1/2/foo'
[[1,2],"foo"]
$ curl 'localhost:8080/example/1/2/3'
[[1,2,3],null]
$ curl 'localhost:8080/example/foo'
[[],"foo"]

The server uses backtracking when parsing the route so the server knows when the Ints end and the Text begins.

Types

The whole thing is strongly typed, which means several things in the context of service programming.

For example, if you define a data type that expects an Int field, then by golly your handler will get an Int field or the server will automatically reject the request for you. You don't have to worry about checking that the field is present nor do you need to validate that the parameter decodes to an Int correctly. If you want the parameter to be optional then you need to make that explicit by marking the field as type Maybe Int.

You also don't have to handle fields that belong to other endpoints. Each endpoint only gets exactly the fields it requested; no more, no less. If a given endpoint gets the wrong set of path tokens or query parameters then the server rejects the request for you.

This is also strongly typed in the sense that more logic is pushed into the type and less logic goes in the handler. If you want just the first or last occurrence of a query parameter, you just annotate the type with First or Last, respectively. The more logic you push into declarative type-level programming the more you distill your handler to focus on business logic.

Caveats

I wrote this library to provide a quick an easy way to spin up Haskell web services but the library could still use some improvement. I'm not really a web developer so I only kind of know what I'm doing and could use help from people more knowledgeable than me.

The most notable deficiency is that the library does not take care to serve proper HTTP status codes for different types of errors. Every failed request returns a 404 status code.

Also, if the route is malformed the error message is a completely unhelpful "404 Not Found" error message that doesn't indicate how to fix the error.

Another blatant deficiency is that the server completely ignores the request method. I wasn't sure how to design this to work within the framework of data type generic programming.

If you have ideas about how to improve things I would greatly welcome any contributions.

Conclusions

People familiar with Haskell will recognize that this library resembles the servant library in some respects. The high-level difference is that this is a subset of servant that is much simpler but also significantly less featureful. For example, servant can also generate client-side bindings and Swagger resource declarations and servant also permits a much greater degree of customization.

This library focuses primarily on simple quick-and-dirty services; for anything more polished and production-ready you will probably want to try other Haskell service libraries. I just wanted to make it as easy as possible for people to get started with back-end development in Haskell and also show off how cool and powerful GHC generics can be.

If you would like to learn more about this library you can read the tutorial or if you would like to use the library you can obtain the code from Hackage or Github.

Categories: Offsite Blogs

Neil Mitchell: More space leaks: Alex/Happy edition

Planet Haskell - Tue, 07/05/2016 - 6:43am

Summary: Alex and Happy had three space leaks, now fixed.

Using the techniques described in my previous blog post I checked happy and alex for space leaks. As expected, both had space leaks. Three were clear and unambiguous space leaks, two were more nuanced. In this post I'll describe all five, starting with the obvious ones.

1: Happy - non-strict accumulating fold

Happy contains the code:

indexInto :: Eq a => Int -> a -> [a] -> Maybe Int
indexInto _ _ [] = Nothing
indexInto i x (y:ys) | x == y = Just i
| otherwise = indexInto (i+1) x ys

This code finds the index of an element in a list, always being first called with an initial argument of 0. However, as it stands, the first argument is a classic space leak - it chews through the input list, building up an equally long chain of +1 applications, which are only forced later.

The fix is simple, change the final line to:

let j = i + 1 in j `seq` indexInto j x ys

Or (preferably) switch to using the space-leak free Data.List.elemIndex. Fixed in a pull request.

2: Happy - sum using foldr

Happy also contained the code:

foldr (\(a,b) (c,d) -> (a+b,b+d)) (0,0) conflictList

The first issue is that the code is using foldr to produce a small atomic value, when foldl' would be a much better choice. Even after switching to foldl' we still have a space leak because foldl' only forces the outer-most value - namely just the pair, not the Int values inside. We want to force the elements inside the pair so are forced into the more painful construction:

foldl' (\(a,b) (c,d) ->
let ac = a + c; bd = b + d
in ac `seq` bd `seq` (ac,bd))
(0,0) conflictList

Not as pleasant, but it does work. In some cases people may prefer to define the auxiliary:

let strict2 f !x !y = f x y
in foldr (\(a,b) (c,d) -> strict2 (,) (a+b) (b+d)) (0,0) conflictList

Fixed in a pull request.

3: Alex - lazy state in a State Monad

Alex features the code:

N $ \s n _ -> (s, addEdge n, ())

Here N roughly corresponds to a state monad with 2 fields, s and n. In this code n is a Map, which operates strictly, but the n itself is not forced until the end. We solve the problem by forcing the value before returning the triple:

N $ \s n _ -> let n' = addEdge n in n' `seq` (s, n', ())

Fixed in a pull request.

4: Alex - array freeze

Alex calls the Data.Array.MArray.freeze function, to convert an STUArray (unboxed mutable array in the ST monad) into a UArray (unboxed immutable array). Unfortunately the freeze call in the array library uses an amount of stack proportional to the size of the array. Not necessarily a space leak, but not ideal either. Looking at the code, it's also very inefficient, constructing and deconstructing lots of intermediate data. Fortunately under normal optimisation a rewrite rule fires for this type to replace the call with one to freezeSTUArray, which is much faster and has bounded stack, but is not directly exported.

Usually I diagnose space leaks under -O0, on the basis that any space leak problems at -O0 may eventually cause problems anyway if an optimisation opportunity is lost. In this particular case I had to -O1 that module.

5: Happy - complex fold

The final issue occurs in a function fold_lookahead, which when given lists of triples does an mconcat on all values that match in the first two components. Using the extra library that can be written as:

map (\((a,b),cs) -> (a,b,mconcat cs)) .
groupSort .
map (\(a,b,c) -> ((a,b),c))

We first turn the triple into a pair where the first two elements are the first component of the pair, call groupSort, then mconcat the result. However, in Happy this construction is encoded as a foldr doing an insertion sort on the first component, followed by a linear scan on the second component, then individual mappend calls. The foldr construction uses lots of stack (more than 1Mb), and also uses an O(n^2) algorithm instead of O(n log n).

Alas, the algorithms are not identical - the resulting list is typically in a different order. I don't believe this difference matters, and the tests all pass, but it does make the change more dangerous than the others. Fixed in a pull request.

The result

Thanks to Simon Marlow for reviewing and merging all the changes. After these changes Happy and Alex on the sample files I tested them with use < 1Kb of stack. In practice the space leaks discovered here are unlikely to materially impact any real workflows, but they probably go a bit faster.

Categories: Offsite Blogs

Philip Wadler: Roseburn to Leith Walk Cycleway: the website

Planet Haskell - Tue, 07/05/2016 - 3:38am
There is a new website in support of the Roseburn to Leith Walk Cycleway. I especially like their promise to be evidence-based and to cover both sides, something increasingly rare in political discourse.
We are an informal association of local residents working to get the best for our community from the Proposed Cycle Route.  We've spent hundreds of hours gathering the facts.
  1. Even if you don't cycle, the Cycle Route has big benefits for you
  2. Common concerns don't match the facts
  3. The Council's latest revised design has addressed key concerns.
Our promiseOur site is evidence-based, including the disadvantages.  We are ready to engage in discussion with anyone.  Tell us about errors or omissions and we'll fix them as soon as we can.
Our goals
  • Get the best for all residents. This is not a website advocating cycling.  It's true that many of the founders do cycle, and many of us also drive.
  • Make decisions based on the facts.  We are concerned how many people are voicing fears and criticisms yet don't seem to know about some of the most important data and studies.
  • Listen to all views, and bring people together for discussion.  We don't accept the whole notion of classifying people as 'cyclists' and 'drivers'.  We are all ordinary people who use a variety of means of travel appropriate to different situations.
Categories: Offsite Blogs

Yesod Web Framework: New http-client and mono-traversable releases

Planet Haskell - Tue, 07/05/2016 - 12:15am

I'm happy to announce the release of a number of packages today, but mostly this comes down to upgrades to http-client and mono-traversable. This blog post will cover the main changes you should be aware of it you are using one of these two packages. In addition to these two packages, the following related packages are being released as well: http-client-tls, http-client-openssl, http-conduit, mono-traversable-instances, minlen, chunked-data, conduit-combinators, mutable-containers, classy-prelude, classy-prelude-conduit, classy-prelude-yesod.

http-client

http-client is an HTTP client library leveraged by a number of other packages, including http-conduit, pipes-http, and wreq. This release is mostly about addressing issue #193, about an controversial design decision to throw runtime exceptions on non-successful HTTP response statuses. If you want a quick explanation of what's changed and what you should do:

  • If the HTTP server you're talking to gives a non-success HTTP response status (e.g., 404 not found), you will no longer get a runtime exception by default.

    • If you want the old behavior, switch to the parseUrlThrow function
    • The parseUrl function remains with the old behavior, but is deprecated in favor of parseRequest
    • The IsString instance has also switched to the non-throwing behavior
  • In an effort to make the remaining exceptions more useful, and avoid people accidentally relying on the old exception behavior, there's a new structure to the HttpException type. In particular, almost all exceptions are now contained in the HttpExceptionContent type, and will be wrapped up with the HttpExceptionRequest constructor, which provies information on the Request used to generate the exception. Hopefully this will make for much more useful error messages.

Based on the feedback I've received, this should bring the default behavior for http-client into line with what people expect, and will hopefully have a minimal impact of migration for existing users relying on the current behavior.

mono-traversable

The mono-traversable package provides a typeclass hierarchy based around the idea of monomorphic containers. This allows, for examples, a unified foldMap function that works on lists, ByteStrings, and unboxed vectors, as well as abstractions over sequences (functions like break and drop) and containers (Maps and Sets).

I laid out a plan for a cleanup of the mono-traversable package. Most of the changes here were minor, and will not affect end users. Of import:

  • The mono-traversable package itself has much reduced dependencies, by putting a number of instances into the new mono-traversable-instances package.
  • A few typeclasses that used to live in chunked-data have moved to mono-traversable
  • The Data.NonNull module is much simpler, and no longer based on Data.MinLen (which lives on in the minlen package)
classy-prelude

Mostly, classy-prelude is just inheriting the upstream changes in mono-traversable. The only other point I'd like to make about this classy-prelude release is that it is switching over to the new safe-exceptions package, which I recently announced on the FP Complete blog.

Mega repo

To simplify maintenance, and address a common problem of people not knowing which repo to report issues to, I've combined a few repos together into a mono-traversable mega-repo:

  • classy-prelude (and -conduit and -yesod)
  • chunked-data
  • mutable-containers

I've updated the old repo locations with a final commit pointing to the new location.

Categories: Offsite Blogs

Intanciate data type

haskell-cafe - Mon, 07/04/2016 - 9:43pm
Hi all, I have a data type looking like this: data Foo e a where Foo :: e → Foo e a I would like to instantiate it to make it equivalent to: data Bar a where A :: String → Bar Int B :: Maybe a → Bar a How can I do that? With a functional dependency? I probably need to change the definition of Foo. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
Categories: Offsite Discussion

Ken T Takusagawa: [vuqzjhmd] Heptagon

Planet Haskell - Mon, 07/04/2016 - 3:51pm

Rainbow-shaded regular heptagon.  The source code below draws it in two different ways. It is unfortunate that the JuicyPixels Codec.Picture generateImage mapPixels encodePng pipeline (implemented in the function heptagonpic) is not lazy.  A 32000 by 32000 image ran out of memory.  The alternative route, outputting a Netpbm PPM (implemented in the function heptagon) then piping standard output to pnmtopng worked just fine.

There is a curious optical illusion of radial spikes, especially in the red and cyan.

Source code in Haskell.

Categories: Offsite Blogs