News aggregator

5outh/Bang · GitHub

del.icio.us/haskell - Wed, 11/19/2014 - 9:27pm
Categories: Offsite Blogs

acowley.github.io

del.icio.us/haskell - Wed, 11/19/2014 - 7:07pm
Categories: Offsite Blogs

Christopher Done: Lucid 2.0: clearer than before

Planet Haskell - Wed, 11/19/2014 - 6:00pm

Since my last post about Lucid, I’ve updated Lucid to major version 2.0 in a way that removes the need for the with combinator. Now, you can just write:

term_ <children> term_ [<props>] <children>

Example:

page :: Html () page = html_ (do head_ (do title_ "Introduction page." link_ [rel_ "stylesheet",type_ "text/css",href_ "screen.css"] style_ "body{background:red}") body_ (do div_ [id_ "header",style_ "color:white"] "Syntax" p_ (span_ (strong_ "This is an example of Lucid syntax.")) hr_ [] ul_ (mapM_ (li_ . toHtml . show) [1,2,3]) table_ (tr_ (do td_ "Hello!" td_ [class_ "alt"] "World!" td_ "Sup?"))))

Here’s the (pretty printed) output:

λ> page <!DOCTYPE html> <html> <head> <title>Introduction page.</title> <link href="screen.css" rel="stylesheet" type="text/css"> <style>body{background:red}</style> </head> <body> <div id="header" style="color:white">Syntax</div> <p><span><strong>This is an example of Lucid syntax.</strong></span></p> <hr> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> <table> <tr> <td>Hello!</td> <td class="alt">World!</td> <td>Sup?</td> </tr> </table> </body> </html> Overloaded

Element terms are now typed like this:

p_ :: Term arg result => arg -> result

Giving a couple overloaded instances:

p_ :: Monad m => [Attribute] -> HtmlT m () -> HtmlT m () p_ :: Monad m => HtmlT m () -> HtmlT m ()

This is similar to the variadic printf from Text.Printf, but limited to one level of variance.

Retaining old invariants

In my last post I listed a bunch of factors that Lucid should solve, I worked hard to make sure these were met in this change.

Preserving liberal term use

You can still use style_ or title_ as an element or an attribute:

λ> style_ [style_ "inception"] "Go deeper." :: Html () <style style="inception">Go deeper.</style> Preserving encoding properties

The script_ and style_ elements still output unencoded:

λ> script_ "alert('Hello!' > 12)" :: Html () <script>alert('Hello!' > 12)</script> With is still available

You can still add attributes to elements using with:

λ> p_ [id_ "foo"] "" :: Html () <p id="foo"></p> λ> with (p_ [id_ "foo"]) [class_ "red"] "yo" :: Html () <p id="foo" class="red">yo</p> Convenient construction of custom elements

You can construct custom elements if needed:

λ> with (term "potato" [id_ "foo"]) [class_ "red"] "yo" :: Html () <potato id="foo" class="red">yo</potato>

But you can also construct normal elements with a custom class, so that you don’t have to use with for extending elements like our old container_ example, you can construct an element with some given attributes:

λ> let container_ = termWith "div" [class_ " container "]

And then use it later like a normal element:

λ> container_ [class_ "main"] "OK, go!" :: Html () <div class=" container main">OK, go!</div>

Some basic Bootstrap terms are available in Lucid.Bootstrap.

Still a monad transformer

I didn’t change anything about the monad itself. Just the combinators. So you can still use it as a transformer:

λ> runReader (renderTextT (html_ (body_ (do name <- lift ask p_ [class_ "name"] (toHtml name))))) ("Chris" :: String) "<html><body><p class=\"name\">Chris</p></body></html>" Small trade-off

One small difference is that elements that take no children always take arguments:

-- | @input@ element input_ :: Monad m => [Attribute] -> HtmlT m () input_ = with (makeElementNoEnd "input")

So you will always write:

input_ [<something>]

But in practice it seems that elements with no children almost always take a number of attributes. Exceptions to that rule are br_ and hr_, but those are quite rare. So this is a very happy trade-off, I feel. (See the ‘real examples’ at the end of this post.)

Extending elements like this is straight-forward using our usual with combinator. Example, suppose you’re sick of writing the classic input type="text", you can define a combinator like this:

text_ :: Monad m => [Attribute] -> HtmlT m () text_ = with (with (makeElementNoEnd "input") [type_ "text"])

And now you can write:

λ> text_ [] <input type="text"> λ> text_ [class_ "foo"] <input type="text" class="foo"> Larger trade-off

Due to the overloadedness, similar to the overloaded strings example:

λ> "foo > bar" :: Html () foo &gt; bar

You have to use a type annotation in GHCi:

λ> p_ "foo" :: Html () <p>foo</p>

Otherwise you get

No instance for (Term arg0 a0) arising from a use of it

Most Haskellers won’t care about this case, but for GHCi users it’s a slight regression. Also, in some local where declarations, you might need a type signature. For example, the following is OK:

people :: Html () people = ul_ (mapM_ person ["Mary Smith","Dave Jones"]) where person name = li_ name

Whereas in this case:

bigTable :: [[Int]] -> Html () bigTable t = table_ (mapM_ row t) where row r = tr_ (mapM_ (td_ . toHtml . show) r)

It’s a little harder for GHC to infer this, so you add a type-signature:

bigTable :: [[Int]] -> Html () bigTable t = table_ (mapM_ row t) where row :: [Int] -> Html () row r = tr_ (mapM_ (td_ . toHtml . show) r)

Not a big deal given the benefits, but something to be aware of.

Summary

In total, I’ve made this library almost perfect for my own tastes. It’s concise, easy to read and edit (and auto-format), it lacks namespace issues, it’s easy to make re-usable terms, and it’s fast enough. The need for the with combinator was the only wart that naggled me over the past week, I knew I’d end up making some change. I’ve also covered the trade-offs that come with this design decision.

As far as I’m concerned, Lucid can rest at major version 2.* for a long time now. I added some newfangled HTML5 elements (who knew main was now an element?) and a test suite. You can expect the only minor version bumps henceforth to be bugfixes, regression tests, and more documentation.

For some real examples:

Categories: Offsite Blogs

Christopher Done: Lucid: templating DSL for HTML

Planet Haskell - Wed, 11/19/2014 - 6:00pm

I’m not big on custom templating languages, for reasons I’ll write about another time. I prefer EDSLs. I preferred the xhtml package back when that was what everybody used. It looked like this:

header << thetitle << "Page title" thediv noHtml ! [theclass "logo"] << "…" thediv noHtml ! [identifier "login"]

Pretty line-noisy to read, write and hard to edit in a reasonable manner.

Later, blaze-html became the new goto HTML writing library. It improved upon the XHTML package by being faster and having a convenient monad instance. It looks like this:

page1 = html $ do head $ do title "Introduction page." link ! rel "stylesheet" ! type_ "text/css" ! href "screen.css" body $ do div ! id "header" $ "Syntax" p "This is an example of BlazeMarkup syntax." ul $ mapM_ (li . toMarkup . show) [1, 2, 3]

Much easier to read, write and edit thanks to the monad instance.

However, after several years of using that, I’ve come to write my own. I’ll cover the infelicities about Blaze and then discuss my alternative approach.

Reading back through what I’ve written below, it could be read as a bit attacky, and some of the issues are less philosophical and more incidental. I think of it more that the work on writing HTML in a DSL is incomplete and to some degree people somewhat gave up on doing it more conveniently at some point. So I’m re-igniting that.

The combination of having a need to write a few HTML reports and recent discussions about Blaze made me realise it was time for me to come at this problem a-fresh with my own tastes in mind. I also haven’t used my own approach much, other than porting some trivial apps to it.

Blaze Names that conflict with base

The first problem is that Blaze exports many names which conflict with base. Examples:

div, id, head, map

The obvious problem with this is that you either have to qualify any use of those names, which means you have to qualify Blaze, and end up with something inconsistent like this:

H.div ! A.id "logo" $ "…"

Where H and A come from importing the element and attribute modules like this:

import qualified Text.Blaze.Html5 as H import qualified Text.Blaze.Html5.Attributes as A

Or you don’t import Prelude and only import Blaze, but then you can’t do a simple map without qualification.

You might’ve noticed in the old xhtml package that thediv and identifier are used instead. The problem with using different names from the actual things they refer to is that they’re hard to learn and remember, both for regular Haskellers and newbies coming to edit your templates.

Names that are keywords

This is a common problem in DSLs, too. In Blaze the problem is: class or type (perhaps others I don’t recall). Blaze solves it with: class_ or type_

Again, the problem with this is that it is inconsistent with the other naming conventions. It’s another exception to the rule that you have to remember and makes the code look bad.

Conflicting attribute and element names

There are also names which are used for both attributes and elements. Examples are style and map. That means you can’t write:

H.head $ style "body { background: red; }" body $ p ! style "foo" $ …

You end up writing:

H.head $ H.style "body { background: red; }" body $ p ! A.style "foo" $ … Inconsistency is difficult and ugly

What the above problems amount to is ending up with code like this:

body $ H.div ! A.id "logo" ! class_ "left" ! hidden $ "Content"

At this point users of Blaze give up with second-guessing every markup term they write and decide it’s more consistent to qualify everything:

H.body $ H.div ! A.id "logo" ! A.class_ "left" ! A.hidden $ "Content"

Or, taken from some real code online:

H.input H.! A.type_ "checkbox" H.! A.checked True H.! A.readonly "true"

This ends up being too much. Inconvenient to type, ugly to read, and one more step removed from the HTML we’re supposed to be generating.

The Monad instance isn’t

The monad instance was originally conceived as a handy way to write HTML nicely without having to use <> or lists of lists and other less wieldy syntax.

In the end the monad ended up being defined like this:

instance Monad MarkupM where return _ = Empty {-# INLINE return #-} (>>) = Append {-# INLINE (>>) #-} h1 >>= f = h1 >> f (error "Text.Blaze.Internal.MarkupM: invalid use of monadic bind") {-# INLINE (>>=) #-}

And has been for some years. Let’s take a trivial example of why this is not good. You render some HTML and while doing so build a result to be used later:

do xs <- foldM (\c i -> …) mempty ys mapM_ dd xs

Uh-oh:

*** Exception: Text.Blaze.Internal.MarkupM: invalid use of monadic bind The overloaded strings instance is bad

The previous point leads onto this next point, which is that due to this phantomesque monad type, the instance is like this:

instance IsString (MarkupM a) where fromString = Content . fromString {-# INLINE fromString #-}

How can it make this value? It cannot. If you want to go ahead and extract that `a’, you get:

*** Exception: Text.Blaze.Internal.MarkupM: invalid use of monadic bind

Additionally, this instance is too liberal. You end up getting this warning:

A do-notation statement discarded a result of type GHC.Prim.Any

Suppress this warning by saying _ <- "Example" or by using the flag -fno-warn-unused-do-bind

So you end up having to write in practice (again, taken from a real Blaze codebase by one of the authors):

void "Hello!"

Which pretty much negates the point of using IsString in the first-place. Alternatively, you use -fno-warn-unused-do-bind in your module.

Working with attributes is awkward

The ! syntax seems pretty convenient from superficial inspection:

link ! rel "stylesheet" ! type_ "text/css" ! href "screen.css"

But in practice it means you always have the same combination:

div ! H.class_ "logo" $ "…"

Which I find—personally speaking—a bit distasteful to read, it’s not far from what we saw in the old xhtml package:

thediv ! [theclass "logo"] << "…"

Did we really save that much in the attribute department? Operators are evil.

But mostly presents an editing challenge. Operators like this make it tricky to navigate, format in a regular way and do code transformations on. All Haskell code has operators, so this is a general problem. But if your DSL doesn’t actually need these operators, I consider this a smell.

Attributes don’t compose

You should be able to compose with. For example, let’s say you want to define a re-usable component with bootstrap:

container inner = div ! class_ "container" $ inner

Now you can use it to make a container. But consider now that you also want to add additional attributes to it later. You can do that with another call to with:

container ! class_ "main" $ "zot"

In Blaze this produces:

λ> main "<div class=\"container\" class=\"main\">My content!</div>"

Browsers ignore the latter main, so the composition didn’t work.

Ceremony is tiring

Here’s the example from Blaze’s package, that’s introduced to users.

import Prelude hiding (head, id, div) import Text.Blaze.Html4.Strict hiding (map) import Text.Blaze.Html4.Strict.Attributes hiding (title) import Text.Blaze.Renderer.Utf8 (renderMarkup) page1 :: Markup page1 = html $ do head $ do title "Introduction page." link ! rel "stylesheet" ! type_ "text/css" ! href "screen.css" body $ do div ! id "header" $ "Syntax" p "This is an example of BlazeMarkup syntax." ul $ mapM_ (li . toMarkup . show) [1, 2, 3] main = print (renderMarkup page1)

Apart from the import backflips you have to do to resolve names properly, you have at least three imports to make just to render some HTML. Call me lazy, or stupid, but I never remember this deep hierarchy of modules and always have to look it up every single time. And I’ve been using Blaze for as long as the authors have.

Transforming

A smaller complaint is that it would sometimes be nice to transform over another monad. Simplest example is storing the read-only model information in a reader monad and then you don’t have to pass around a bunch of things as arguments to all your view functions. I’m a big fan of function arguments for explicit state, but not so much if it’s the same argument every time.

No Show instance

It would be nice if you could just write some markup in the REPL without having to import some other modules and wrap it all in a function just to see it.

Lucid

My new library, Lucid, attempts to solve most of these problems.

Naming issues

Firstly, all names which are representations of HTML terms are suffixed with an underscore _:

p_, class_, table_, style_

No ifs or buts. All markup terms.

That solves the following problems (from the issues described above):

  • Names that conflict with base: div_, id_, head_, map_, etc.
  • Names that are keywords: class_, type_, etc.
  • Conflicting attribute and element names: solved by abstracting those names via a class. You can write style_ to mean either the element name or the attribute name.
  • Inconsistency is difficult and ugly: there’s no inconsistency, all names are the same format.

No import problems or qualification. Just write code without worrying about it.

How it looks

Plain text is written using the OverloadedStrings and ExtendedDefaultRules extensions, and is automatically escaped:

λ> "123 < 456" :: Html () 123 &lt; 456

Elements nest by function application:

λ> table_ (tr_ (td_ (p_ "Hello, World!"))) <table><tr><td><p>Hello, World!</p></td></tr></table>

Elements are juxtaposed via monoidal append:

λ> p_ "hello" <> p_ "sup" <p>hello</p><p>sup</p>

Or monadic sequencing:

λ> div_ (do p_ "hello"; p_ "sup") <div><p>hello</p><p>sup</p></div>

Attributes are set using the with combinator:

λ> with p_ [class_ "brand"] "Lucid Inc" <p class="brand">Lucid Inc</p>

Conflicting attributes (like style_) work for attributes or elements:

λ> html_ (head_ (style_ "body{background:red}") <> with body_ [style_ "color:white"] "Look ma, no qualification!") <html><head><style>body{background:red}</style></head> <body style="color:white">Look ma, no qualification!</body></html> The Blaze example

For comparison, here’s the Blaze example again:

page1 = html $ do head $ do title "Introduction page." link ! rel "stylesheet" ! type_ "text/css" ! href "screen.css" body $ do div ! id "header" $ "Syntax" p "This is an example of BlazeMarkup syntax." ul $ mapM_ (li . toMarkup . show) [1, 2, 3]

And the same thing in Lucid:

page2 = html_ $ do head_ $ do title_ "Introduction page." with link_ [rel_ "stylesheet",type_ "text/css",href_ "screen.css"] body_ $ do with div_ [id_ "header"] "Syntax" p_ "This is an example of Lucid syntax." ul_ $ mapM_ (li_ . toHtml . show) [1,2,3]

I’m not into operators like ($) and swung indentation like that, but I followed the same format.

I’d write it in a more Lispy style and run my hindent tool on it:

page1 = html_ (do head_ (do title_ "Introduction page." with link_ [rel_ "stylesheet" ,type_ "text/css" ,href_ "screen.css"]) body_ (do with div_ [id_ "header"] "Syntax" p_ "This is an example of Lucid syntax." ul_ (mapM_ (li_ . toHtml . show) [1,2,3])))

But that’s another discussion.

It’s a real monad

Normal monadic operations work properly:

λ> (return "OK!" >>= p_) <p>OK!</p>

It’s basically a writer monad.

In fact, it’s also a monad transformer:

λ> runReader (renderTextT (html_ (body_ (do name <- lift ask p_ (toHtml name))))) ("Chris" :: String) "<html><body><p>Chris</p></body></html>" Overloaded strings instance is fine

The instance is constrained over the return type being (). So string literals can only be type HtmlT m ().

λ> do "x" >> "y" :: Html () xy λ> do x <- "x"; toHtml (show x) x() Attributes

Attributes are simply written as a list. That’s all. Easy to manipulate as a data structure, easy to write and edit, and automatically indent in a predictable way:

λ> with p_ [id_ "person-name",class_ "attribute"] "Mary" <p id="person-name" class="attribute">Mary</p>

No custom operators are required. Just the with combinator. If you want to indent it, just indent it like normal function application:

with p_ [id_ "person-name",class_ "attribute"] "Mary"

And you’re done.

Composing attributes

You should be able to compose with. For example, let’s say you want to define a re-usable component with bootstrap:

λ> let container_ = with div_ [class_ "container "]

Now you can use it to make a container:

λ> container_ "My content!" <div class="container ">My content!</div>

But consider now that you also want to add additional attributes to it later. You can do that with another call to with:

λ> with container_ [class_ "main"] "My content!" <div class="container main">My content!</div>

Duplicate attributes are composed with normal monoidal append. Note that I added a space in my definition of container anticipating further extension later. Other attributes might not compose with spaces.

Unceremonious

Another part I made sure was right was lack of import nightmare. You just import Lucid and away you go:

λ> import Lucid λ> p_ "OK!" <p>OK!</p> λ> p_ (span_ (strong_ "Woot!")) <p><span><strong>Woot!</strong></span></p> λ> renderBS (p_ (span_ (strong_ "Woot!"))) "<p><span><strong>Woot!</strong></span></p>" λ> renderToFile "/tmp/foo.html" (p_ (span_ (strong_ "Woot!")))

If I want to do more advanced stuff, it’s all available in Lucid. But by default it’s absolutely trivial to get going and output something.

Speed

Actually, despite having a trivial implementation, being a real monad and a monad transformer, it’s not far from Blaze. You can compare the benchmark reports here. A quick test of writing 38M of HTML to file yielded the same speed (about 1.5s) for both Lucid and Blaze. With such decent performance for very little work I’m already ready to start using it for real work.

Summary

So the point of this post was really to explain why another HTML DSL and I hope I did that well enough.

The code is on Github. I pushed to Hackage but you can consider it beta for now.

Categories: Offsite Blogs

FP Complete: Stackage server: new features and open source

Planet Haskell - Wed, 11/19/2014 - 6:00pm
Open source

We've been working on Stackage server for a while and now that the code has stabilized it's ready to be open source. You can fork it on Github! We're a responsive team, used to bringing pull requests forward and getting them deployed.

Since the last update we added a bunch of things. Here's a rundown:

Clarifying improvements
  • Recommended snapshots: The home page now lists recommended snapshots for GHC 7.8, GHC 7.8 Haskell Platform flavour, and GHC 7.6. Makes it a little more straight-forward where to start.

  • Snapshots: The snapshots page has been cleaned up a bit to cleanly separate times when snapshots are uploaded. Just an aesthetic improvement.

  • We also reorganized the Preparing your system to use Stackage wiki page to be more straight-forward to get started.

Packages

We now list all packages from Hackage on the packages page. A subset of these are included in Stackage snapshots. Hitting those links takes you to our new page package. Examples:

On this page we display:

  • Metadata for the most recently uploaded version of that package:

    • Name, version, license, authorship, maintainer
  • We also display the dependencies of that package. Notice that there are no version constraints. That information is stored in the snapshot itself.

  • Documentation versions: each snapshot that contains a version of this package will be listed along with documentation for that version.

README

We support showing a README from your package (see e.g. hlint example above), which is a really nice way to introduce people to your package. You can use the same one that you use for your Github README.md, just include it in your .cabal file with:

extra-source-files: README.md

If your filename is just README it'll be included as plain text. With the .md extension it will be rendered as markdown.

Please do go ahead and include your README.md in your .cabal file. If you don't have one, please write one and make it helpful and descriptive for any newbies to your package.

If no README file is found it falls back to the package description, which is displayed as plain text. As is well-known in the community at large, writing descriptive pros in Haddock syntax is not pleasant, whereas everyone is pretty much writing their READMEs in markdown anyway thanks to Github.

CHANGELOGs are also displayed as markdown if the file extension is .md, otherwise it's treated as plain text.

Specifying remote-repo in sandboxes

An issue with using Stackage in the past was that you had to either put your remote-repo field in your global cabal config, or setup an hsenv. Or by using a cabal.config with constraints in it. Now the feature has been merged to be able to specify remote-repo in the cabal.config file in your project root. Once this is released you'll be able to use a Stackage snapshot within a sandbox and keep the cabal.config file in your source repository.

Additional package page features

Additional features include:

  • Tagging: tagging a package is easy: you just click the + button, type something and hit return.

    We try to keep the tags of a simple format (a slug), so if you type characters that shouldn't be in there, it'll remove them and then prompt you to confirm.

    Related: if you click a tag it will take you to a page of all packages tagged with that, e.g. parsing.

    Finally, there is a list of all tags. Currently it's rather small because that's just what I populated myself.

  • Likes: just upvote a package if you like it. Hit the thumbs up icon.

  • Comments: comments are provided by Disqus. It's very easy to comment with Disqus, you can use your normal account.

    If you're interested in a package, or are an author, you can hit the Subscribe link displayed at the bottom of the page to subscribe to that discussion to get updates of future comments.

Additional to the other metadata, like Github, we make use of the files in your package, so we will also display:

Summary

Stackage just got easier to use:

  • The site is clearer now.
  • The wiki guide is easier.
  • Using Stackage from a sandbox will soon be very easy.
  • You can browse documentation of your snapshot on Stackage via the snapshot (e.g. here).
  • Or you can start from the package list and view an individual package, vote and tag it.
  • It's open source!
Categories: Offsite Blogs

Kototama: Four Haskell books

Planet Haskell - Wed, 11/19/2014 - 5:00pm

In 2013 and 2014 I read four Haskell books. In this post I’m making mini-reviews for each of them, chronologically ordered.

Learn you a Haskell for Great Good

Learn you a Haskell for Great Good is one of the best computer science book I had the occasion to read, and I even admit I was a little sad once I finished it! It exposes the main concepts of Haskell in a very pedagogic way and clear writing style. After reading the book, functors, applicative and monads become easily understandable. The only drawback is that this book is not enough to start with Haskell, there are no explanations of how to create a Haskell project using Cabal, use libraries, test your application etc. I think it’s okay for an introductory book but one should be informed. The book is suited for people without experience with Haskell or functional programming.

Developing Web Applications with Haskell and Yesod

I read Developing Web Applications with Haskell and Yesod to discover other ways of building web applications, as I mostly had experience with Clojure and Compojure. I enjoyed reading this book which is short but contains a lot, going from the frontend to the backend and explaining a lot of subjects: HTML templates, sessions, authentification, persistence with databases etc. You discover how a statically typed language can help you building a web application with more guarantees. The only drawback for me was that even after reading one book on Haskell, some of the type signatures of functions were still hard to understand. Some familiarity with monad transformers prior to reading this book may help.

Real World Haskell

The goal of Real World Haskell was to bring Haskell to a less academic audience by showing how Haskell could be used for “real world” applications, at a time where there weren’t so many Haskell books there. In this sense I think the book succeed. There are a lot of interesting subjects tackled in this book, like profiling and performance analysis but I did not really enjoy reading it. Either the examples were a bit boring or the writing style was too dry for me, in the end I had to fight to finish this very long book (~700 pages!). I nonetheless appreciate that this book exist and I may use it in the future as a reference. The book is a bit outdated and some code are not valid anymore ; it was not a problem for me since I didn’t try out the examples but this should be considered if you want to learn Haskell with it.

Beginning Haskell

Beginning Haskell is a paradoxical book. The truth is this book should not have been published because its edition and proof-reading are too bad. What do you think about a book where the first code sample is wrong? map listOfThings action instead of map action listOfThings on page 4, come one… Also the subtitle reads “a Project-Based approach” but this seems to be exaggerated since you will only get some code samples there and there… That being said, I really enjoyed reading this book! I don’t know if it’s a good introductory book but it’s surely is a correct second book on Haskell. It explains how to use Cabal, test an application, use popular libraries like Conduit, build parsers with attoparsec, building a Web Application with Scotty and Fay etc. It includes advanced topics like type programming (enforcing more constraints at the type-level) and even a small introduction to Idris. Conclusion: either burn it or read it.

Conclusion

There are more and more books on Haskell newly published or coming, this makes me happy as this broaden the Haskell community, shows that it is growing and makes it easier to learn the language. Reading is not enough to learn so at the moment I’m writing small Haskell projects to go from a beginner to intermediate level.

Categories: Offsite Blogs

Is it possible to curry arbitrary arguments to a function? Do I need Template Haskell to do this?

Haskell on Reddit - Wed, 11/19/2014 - 4:21pm

Basically I want to be able to do this:

f :: A -> B -> C -> D -> E -> F f a ? c ? e :: B -> D -> F (f a ? c ? e) b d :: F

The question marks represent arguments that I basically want to be "blank".

This way I can curry the function based on any argument instead of just the last one. I can't really think of a way to make this magic work, except maybe using template haskell (which I don't really know anything about). Any haskell wizards out there want to shed some light on this idea?

EDIT: I mostly mean "partially apply" instead of "curry".

submitted by TheFryeGuy
[link] [22 comments]
Categories: Incoming News

Neil Mitchell: Announcing Shake 0.14

Planet Haskell - Wed, 11/19/2014 - 3:27pm

Summary: Shake 0.14 is now out. The *> operator became %>. If you are on Windows the FilePath operations work differently.

I'm pleased to announce Shake 0.14, which has one set of incompatible changes, one set of deprecations and some new features.

The *> operator and friends are now deprecated

The *> operator has been the Shake operator for many years, but in GHC 7.10 the *> operator is exported by the Prelude, so causes name clashes. To fix that, I've added %> as an alias for *>. I expect to export *> for the foreseeable future, but you should use %> going forward, and will likely have to switch with GHC 7.10. All the Shake documentation has been updated. The &*> and |*> operators have been renamed &%> and |%> to remain consistent.

Development.Shake.FilePath now exports System.FilePath

Previously the module Development.Shake.FilePath mostly exported System.FilePath.Posix (even on Windows), along with some additional functions, but modified normalise to remove /../ and made </> always call normalise. The reason is that if you pass non-normalised FilePath values to need Shake can end up with two names for one on-disk file and everything goes wrong, so it tried to avoid creating non-normalised paths.

As of 0.14 I now fully normalise the values inside need, so there is no requirement for the arguments to need to be normalised already. This change allows the simplification of directly exporting System.FilePath and only adding to it. If you are not using Windows, the changes are:

  • normalise doesn't eliminate /../, but normaliseEx does.
  • </> no longer calls normalise. It turned out calling normalise is pretty harmful for FilePattern values, which leads to fairly easy-to-make but hard-to-debug issues.

If you are using Windows, you'll notice all the operations now use \ instead of /, and properly cope with Windows-specific aspects like drives. The function toStandard (convert all separators to /) might be required in a few places. The reasons for this change are discussed in bug #193.

New features

This release has lots of new features since 0.13. You can see a complete list in the change log, but the most user-visible ones are:

  • Add getConfigKeys to Development.Shake.Config.
  • Add withTempFile and withTempDir for the Action monad.
  • Add -j to run with one thread per processor.
  • Make |%> matching with simple files much faster.
  • Use far less threads, with corresponding less stack usage.
  • Add copyFileChanged.

Plans

I'm hoping the next release will be 1.0!

Categories: Offsite Blogs

Will the performance of lazy code get better with improvements in AI?

Haskell on Reddit - Wed, 11/19/2014 - 10:44am

I often see experienced Haskellers adding strictness annotations to a lot of performance critical code. I, however, can't see why laziness would ever be a bad thing. The laziest program would be one that calculated the bare minimum needed to get an answer, essentially deferring all work that was unnecessary. This leads me to believe that it is how the compiler knows when to be lazy that is the problem, not laziness itself. Would machine learning or artificial intelligence help in this regard?

submitted by briticus557
[link] [18 comments]
Categories: Incoming News