News aggregator

Haskell Weekly News: Issue 303

General haskell list - Thu, 08/28/2014 - 6:40am
Welcome to issue 303 of the HWN, an issue covering crowd-sourced bits of information about Haskell from around the web. This issue covers from August 17 to 23, 2014 Quotes of the Week * monochrom: "point free" can be decomposed to: "point" refers to ".", "free" refers to using no "$". :) Top Reddit Stories * λ Bubble Pop! Domain: chrisuehlinger.com, Score: 97, Comments: 41 Original: [1] http://goo.gl/hVQq2F On Reddit: [2] http://goo.gl/OQWXK2 * The fundamental problem of programming language package management Domain: blog.ezyang.com, Score: 82, Comments: 54 Original: [3] http://goo.gl/fWmA0P On Reddit: [4] http://goo.gl/PfJbY0 * How Programming language subreddits talk (including Haskell) Domain: github.com, Score: 72, Comments: 31 Original: [5] http://goo.gl/2Ef0tB On Reddit: [6] http://goo.gl/KpTH74 * A fast, generic and type-safe image processing library written in Haskell Domain: hackage.haskell.org, Score: 59, Comm
Categories: Incoming News

haskell on hadoop

Haskell on Reddit - Thu, 08/28/2014 - 5:48am

has anyone used haskell on hadoop? What were your experiences? I found hadron which looks pretty nice. (Here's a nice talk on hadron that was posted here a while back.)

Edit: I also need hbase bindings, but it looks like hbase-haskell hasn't been touched for a while

submitted by ludflu
[link] [9 comments]
Categories: Incoming News

Would it be plausible to script games in Haskell on top of a C/C++ engine?

Haskell on Reddit - Thu, 08/28/2014 - 2:04am

Just a random thought of mine I wanted to get an opinion on. I currently C and Python for video game programming but my favorite language is Haskell. Would something like this work well?

submitted by ProbablyALinuxUser
[link] [35 comments]
Categories: Incoming News

Keegan McAllister: Calling a Rust library from C (or anything else!)

Planet Haskell - Thu, 08/28/2014 - 12:18am

One reason I'm excited about Rust is that I can compile Rust code to a simple native-code library, without heavy runtime dependencies, and then call it from any language. Imagine writing performance-critical extensions for Python, Ruby, or Node in a safe, pleasant language that has static lifetime checking, pattern matching, a real macro system, and other goodies like that. For this reason, when I started html5ever some six months ago, I wanted it to be more than another "Foo for BarLang" project. I want it to be the HTML parser of choice, for a wide variety of applications in any language.

Today I started work in earnest on the C API for html5ever. In only a few hours I had a working demo. And this is a fairly complicated library, with 5,000+ lines of code incorporating

It's pretty cool that we can use all this machinery from C, or any language that can call C. I'll describe first how to build and use the library, and then I'll talk about the implementation of the C API.

html5ever (for C or for Rust) is not finished yet, but if you're feeling adventurous, you are welcome to try it out! And I'd love to have more contributors. Let me know on GitHub about any issues you run into.

Using html5ever from C

Like most Rust libraries, html5ever builds with Cargo.

$ git clone https://github.com/kmcallister/html5ever
$ cd html5ever
$ git checkout dev
$ cargo build
Updating git repository `https://github.com/sfackler/rust-phf`
Compiling phf_mac v0.0.0 (https://github.com/sfackler/rust-phf#f21e2a41)
Compiling html5ever-macros v0.0.0 (file:///tmp/html5ever)
Compiling phf v0.0.0 (https://github.com/sfackler/rust-phf#f21e2a41)
Compiling html5ever v0.0.0 (file:///tmp/html5ever)

The C API isn't Cargo-ified yet, so we'll build it using the older Makefile-based system.

$ mkdir build
$ cd build
$ ../configure
$ make libhtml5ever_for_c.a
rustc -D warnings -C rpath -L /tmp/html5ever/target -L /tmp/html5ever/target/deps \
-o libhtml5ever_for_c.a --cfg for_c --crate-type staticlib /tmp/html5ever/src/lib.rs
warning: link against the following native artifacts when linking against this static library
note: the order and any duplication can be significant on some platforms, and so may need to be preserved
note: library: rt
note: library: dl
note: library: pthread
note: library: gcc_s
note: library: pthread
note: library: c
note: library: m

Now we can build an example C program using that library, and following the link instructions produced by rustc.

$ H5E_PATH=/tmp/html5ever
$ gcc -Wall -o tokenize tokenize.c -I $H5E_PATH/capi -L $H5E_PATH/build \
-lhtml5ever_for_c -lrt -ldl -lpthread -lgcc_s -lpthread -lc -lm

$ ./tokenize 'Hello&comma; <i class=excellent>world!</i>'
CHARS : Hello
CHARS : ,
CHARS :
TAG : <i>
ATTR: class="excellent"
CHARS : world!
TAG : </i>

The build process is pretty standard for C; we just link a .a file and its dependencies. The biggest obstacle right now is that you won't find the Rust compiler in your distro's package manager, because the language is still changing so rapidly. But there's a ton of effort going into stabilizing the language for a Rust 1.0 release this year. It won't be too long before rustc is a reasonable build dependency.

Let's look at the C client code.

#include <stdio.h>

#include "html5ever.h"

void put_str(const char *x) {
fputs(x, stdout);
}

void put_buf(struct h5e_buf text) {
fwrite(text.data, text.len, 1, stdout);
}

void do_start_tag(void *user, struct h5e_buf name, int self_closing, size_t num_attrs) {
put_str("TAG : <");
put_buf(name);
if (self_closing) {
putchar('/');
}
put_str(">\n");
}

// ...

struct h5e_token_ops ops = {
.do_chars = do_chars,
.do_start_tag = do_start_tag,
.do_tag_attr = do_tag_attr,
.do_end_tag = do_end_tag,
};

struct h5e_token_sink sink = {
.ops = &ops,
.user = NULL,
};

int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s 'HTML fragment'\n", argv[0]);
return 1;
}

struct h5e_tokenizer *tok = h5e_tokenizer_new(&sink);
h5e_tokenizer_feed(tok, h5e_buf_from_cstr(argv[1]));
h5e_tokenizer_end(tok);
h5e_tokenizer_free(tok);
return 0;
}

The struct h5e_token_ops contains pointers to callbacks. Any events we don't care to handle are left as NULL function pointers. Inside main, we create a tokenizer and feed it a string. html5ever for C uses a simple pointer+length representation of buffers, which is this struct h5e_buf you see being passed by value.

This demo only does tokenization, not tree construction. html5ever can perform both phases of parsing, but the API surface for tree construction is much larger and I didn't get around to writing C bindings yet.

Implementing the C API

Some parts of Rust's libstd depend on runtime services, such as task-local data, that a C program may not have initialized. So the first step in building a C API was to eliminate all std:: imports. This isn't nearly as bad as it sounds, because large parts of libstd are just re-exports from other libraries like libcore that we can use with no trouble. To be fair, I did write html5ever with the goal of a C API in mind, and I avoided features like threading that would be difficult to integrate. So your library might give you more trouble, depending on which Rust features you use.

The next step was to add the #![no_std] crate attribute. This means we no longer import the standard prelude into every module. To compensate, I added use core::prelude::*; to most of my modules. This brings in the parts of the prelude that can be used without runtime system support. I also added many imports for ubiquitous types like String and Vec, which come from libcollections.

After that I had to get rid of the last references to libstd. The biggest obstacle here involved macros and deriving, which would produce references to names under std::. To work around this, I create a fake little mod std which re-exports the necessary parts of core and collections. This is similar to libstd's "curious inner-module".

I also had to remove all uses of format!(), println!(), etc., or move them inside #[cfg(not(for_c))]. I needed to copy in the vec!() macro which is only provided by libstd, even though the Vec type is provided by libcollections. And I had to omit debug log messages when building for C; I did this with conditionally-defined macros.

With all this preliminary work done, it was time to write the C bindings. Here's how the struct of function pointers looks on the Rust side:

#[repr(C)]
pub struct h5e_token_ops {
do_start_tag: extern "C" fn(user: *mut c_void, name: h5e_buf,
self_closing: c_int, num_attrs: size_t),

do_tag_attr: extern "C" fn(user: *mut c_void, name: h5e_buf,
value: h5e_buf),

do_end_tag: extern "C" fn(user: *mut c_void, name: h5e_buf),

// ...
}

The processing of tokens is straightforward. We pattern-match and then call the appropriate function pointer, unless that pointer is NULL. (Edit: eddyb points out that storing NULL as an extern "C" fn is undefined behavior. Better to use Option<extern "C" fn ...>, which will optimize to the same one-word representation.)

To create a tokenizer, we heap-allocate the Rust data structure in a Box, and then transmute that to a raw C pointer. When the C client calls h5e_tokenizer_free, we transmute this pointer back to a box and drop it, which will invoke destructors and finally free the memory.

You'll note that the functions exported to C have several special annotations:

  • #[no_mangle]: skip name mangling, so we end up with a linker symbol named h5e_tokenizer_free instead of _ZN5for_c9tokenizer18h5e_tokenizer_free.
  • unsafe: don't let Rust code call these functions unless it promises to be careful.
  • extern "C": make sure the exported function has a C-compatible ABI. The data structures similarly get a #[repr(C)] attribute.

Then I wrote a C header file matching this ABI:

struct h5e_buf {
unsigned char *data;
size_t len;
};

struct h5e_buf h5e_buf_from_cstr(const char *str);

struct h5e_token_ops {
void (*do_start_tag)(void *user, struct h5e_buf name,
int self_closing, size_t num_attrs);

void (*do_tag_attr)(void *user, struct h5e_buf name,
struct h5e_buf value);

void (*do_end_tag)(void *user, struct h5e_buf name);

/// ...
};

struct h5e_tokenizer;

struct h5e_tokenizer *h5e_tokenizer_new(struct h5e_token_sink *sink);
void h5e_tokenizer_free(struct h5e_tokenizer *tok);
void h5e_tokenizer_feed(struct h5e_tokenizer *tok, struct h5e_buf buf);
void h5e_tokenizer_end(struct h5e_tokenizer *tok);

One remaining issue is that Rust is hard-wired to use jemalloc, so linking html5ever will bring that in alongside the system's libc malloc. Having two separate malloc heaps will likely increase memory consumption, and it prevents us from doing fun things like allocating Boxes in Rust that can be used and freed in C. Before Rust can really be a great choice for writing C libraries, we need a better solution for integrating the allocators.

If you'd like to talk about calling Rust from C, you can find me as kmc in #rust and #rust-internals on irc.mozilla.org. And if you run into any issues with html5ever, do let me know, preferably by opening an issue on GitHub. Happy hacking!

Categories: Offsite Blogs

Haskell Platform 2014 build problems on OS X

haskell-cafe - Wed, 08/27/2014 - 9:39pm
Hello! I just want to point to your attention this issue of Homebrew: https://github.com/Homebrew/homebrew/issues/31609 It seems that they’re forced to remove the formula for the Haskell Platform because, it seems, the build process has become extremely complicated and they can’t figure out how to automate it. Is there someone that know enough internals of the platform to help them or to give some advice? Thanks, Nicola
Categories: Offsite Discussion

conduit stream fusion

Haskell on Reddit - Wed, 08/27/2014 - 8:04pm
Categories: Incoming News

ANN: cgi 3001.2.0.0

General haskell list - Wed, 08/27/2014 - 7:32pm
Hello, I've just uploaded a new version of cgi to hackage [1]. This release supports GHC 7.8.3, 7.6.3, and 7.4.2. I'm also looking for co-maintainers or backup maintainers of cgi, please email me directly if you're interested. This release was made possible with the assistance and guidance of Carter Schonwald and was based on a patch by Alexander Vershilov. Thanks. [1] http://hackage.haskell.org/package/cgi
Categories: Incoming News

I'm a .NET developer. What can Haskell/Functional Programming teach me?

Haskell on Reddit - Wed, 08/27/2014 - 7:20pm

Hi all, I am a (primarily) .NET developer, though experienced in Smalltalk, Ruby, Java, and a whole list of other things. I like to keep a wide horizon and I've gathered that Functional Programming can teach me good things. A lot of what I do day to day involves the web, typically APIs on HTTP endpoints. I'm not about to completely jump ship to Haskell and FP, but I am certain they can teach me a thing or two and I am eager to embrace it.

I have been using F# a lot lately, but as it is "yet another" .NET language it doesn't feel like true FP. Well, it can be, but the availability of libraries from other languages that clearly aren't FP makes it just too easy to break away from FP I guess? Anyway, I digress.

I understand the syntax of Haskell just fine, I've done plenty of stuff in the GHCI and read many a tutorial. However it just isn't sinking in, I still feel like I am missing something. Like there is some beautiful unicorn of simplicity that is just waiting for me to find it/unlearn the way OO does things/etc.

So, my understanding is that Haskell is a "true" Functional Programming language/platform. I've installed Haskell Platform, and EclipseFP (I'm on Windows without access to *nix for now) and I'm just staring at my project workspace still wondering what I'm not seeing. I've thus far compiled a small web-service using Scotty; However Scotty too didn't feel like FP should feel to me. Shoe-horning the way Sinatra does it into Haskell feels odd.

Am I right to feel odd about this? What am I missing that I should be learning? What would you suggest as a project/task/whatever for me to "get" Functional Programming (and/or Haskell)?

The "No Side Effects" functions "rule": What rule of thumb percentage of the application should this be? Is 100% no side effects even possible? Even with persistence/sessions/cookies/etc?

Many thanks in advance, and I'm sure this question(s) is asked many times so I apologise for that.

submitted by Jestar342
[link] [31 comments]
Categories: Incoming News

Conduit+GHC high memory use for simple Sink

haskell-cafe - Wed, 08/27/2014 - 7:19pm
Hello Cafe, First I'd like to thank Michael Snoyman and Gabriel Gonzalez for the work they've done on the conduit and pipes stream processing libraries, and all the accompanying tutorial content. I've been having fun converting a text processing app from C to Haskell. I'm seeing unexpectedly high memory usage in a stream-processing program that uses the conduit library. I've created a example that demonstrates the problem. The program accepts gzip files as arguments, and for each one, classifies each line as either Even or Odd depending on the length, then outputs some result depending on the Sink used. For each gzip file: action :: GzipFilePath -> IO () action (GzipFilePath filePath) = do result <- runResourceT $ CB.sourceFile filePath $$ Zlib.ungzip =$ CB.lines =$ token =$ sink2 putStrLn $ show result The problem is the following Sink, which counts how many even/odd Tokens are se
Categories: Offsite Discussion

Can somebody explain me the instance Generic Int

Haskell on Reddit - Wed, 08/27/2014 - 3:26pm

Quoting from http://www.haskell.org/ghc/docs/7.6.3/html/libraries/base/src/GHC-Generics.html

-- Int data D_Int data C_Int instance Datatype D_Int where datatypeName _ = "Int" moduleName _ = "GHC.Int" instance Constructor C_Int where conName _ = "" -- JPM: I'm not sure this is the right implementation... instance Generic Int where type Rep Int = D1 D_Int (C1 C_Int (S1 NoSelector (Rec0 Int))) from x = M1 (M1 (M1 (K1 x))) to (M1 (M1 (M1 (K1 x)))) = x

Can somebody explain me what the idea between the three nested M1s is?

And why is the instance Generic Integer missing?

submitted by nh2_
[link] [8 comments]
Categories: Incoming News

[ANN] Wheb 0.3 release

haskell-cafe - Wed, 08/27/2014 - 2:26pm
Hello all, I have been working on a web framework that I use for my personal projects and I thought I would share my small progress. I started this project several months ago when I hit a big bump in difficulty going from a simple skeleton project to a more intricate project using alternative frameworks. Lately I've added three main features: WebSockets, Cache and Redis. WebSockets use the same WhebT interface as the standard HTTP handlers allowing you to share functions and middlware accross your application. Cache is a new plugin for simplistic Caching. It provides an interface to cache ByteStrings under Text keys. Like the other plugins, it is backend agnostic so you can write your own backend or use the prebuilt Redis cache (this requires you to configure your redis instance for caching). In addition to Redis acting as a Cache, you can also use it as a database and as a backend for the plugins Auth and Sessions. You can mix Redis with other plugins. For one of my projects I use the MongoDB plugin f
Categories: Offsite Discussion

Philip Wadler: Informatics Independence Referendum Debate - the result

Planet Haskell - Wed, 08/27/2014 - 7:43am

Here is the outcome of the debate announced earlier:
<embed allowfullscreen="true" allowscriptaccess="always" flashvars="config=http://emedia.is.ed.ac.uk:8080/caped/course_player.xml&amp;file=http://emedia.is.ed.ac.uk:8080/caped/caped_feed.php%3Ffeed%3DD747%26q%3DSPCL" height="360" src="http://emedia.is.ed.ac.uk:8080/JW/player.swf" width="740"></embed>
Before
Yes 19
No 25
Undecided 28

After
Yes 28
No 31
Undecided 26

(Either some people entered after the debate began, or some people began the debate unsure even whether they were undecided.)

Thank you to Alan, Mike, and the audience for a fantastic debate. The audience asked amazing questions on both sides, clearly much involved with the process.

Video of debate here.
Alan's slides here.
My slides here.

Categories: Offsite Blogs

Bill Atkins: NSNotificationCenter, Swift and blocks

Planet Haskell - Wed, 08/27/2014 - 5:21am
The conventional way to register observers with NSNotificationCenter is to use the target-action pattern. While this gets the job done, it's inherently not type-safe.

For example, the following Swift snippet will compile perfectly:

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("itemAdded:"),      name: MyNotificationItemAdded, object: nil)
even though at runtime it will fail unless self has a method named itemAdded that takes exactly one parameter (leaving off that last colon in the selector will turn this line into a no-op). Plus, this method gives you no way to take advantages of Swift's closures, which would allow the observer to access local variables in the method that adds the observer and would eliminate the need to create a dedicated method to handle the event.
A better way to do this is to use blocks. And NSNotificationCenter does include a block-based API:
    NSNotificationCenter.defaultCenter().addObserverForName(MyNotificationItemAdded, object: nil, queue: nil) { note in      // ...    }
This is much nicer, especially with Swift's trailing closure syntax. There are no method names to be looked up at runtime, we can refer to local variables in the method that registered the observer and we can perform small bits of logic in reaction to events without having to create and name dedicated methods.
The catch comes in resource management. It's very important that an object remove its event observers when it's deallocated, or else NSNotificationCenter will try to invoke methods on invalid pointers.
The traditional target-action method has the one advantage that we can easily handle this requirement with a single call in deinit:
  deinit {    NSNotificationCenter.defaultCenter().removeObserver(self)  }
With the block API, however, since there is no explicit target object, each call to addObserverForName returns "an opaque object to act as observer." So your observer class would need to track all of these objects and then remove them all from the notification center in deinit, which is a pain.
In fact, the hassle of having to do bookkeeping on the observer objects almost cancels out the convenience of using the block API. Frustrated by this situation, I sat down and created a simple helper class, NotificationManager:
class NotificationManager {  private var observerTokens: [AnyObject] = []
  deinit {    deregisterAll()  }
  func deregisterAll() {    for token in observerTokens {      NSNotificationCenter.defaultCenter().removeObserver(token)    }
    observerTokens = []  }
  func registerObserver(name: String!, block: (NSNotification! -> ()?)) {    let newToken = NSNotificationCenter.defaultCenter().addObserverForName(name, object: nil, queue: nil) {note in      block(note)      ()    }
    observerTokens.append(newToken)  }    func registerObserver(name: String!, forObject object: AnyObject!, block: (NSNotification! -> ()?)) {    let newToken = NSNotificationCenter.defaultCenter().addObserverForName(name, object: object, queue: nil) {note in      block(note)      ()    }        observerTokens.append(newToken)  }}
First, this simple class provides a Swift-specialized API around NSNotificationCenter.  It provides an additional convenience method without an object parameter (rarely used, in my experience) to make it easier to use trailing-closure syntax. But most importantly, it keeps track of the observer objects generated when observers are registered, and removes them when the object is deinit'd.

A client of this class can simply keep a member variable of type NotificationManager and use it to register its observers. When the parent class is deallocated, the deinit method will automatically be called on its NotificationManager member variable, and its observers will be properly disposed of:

class MyController: UIViewController {  private let notificationManager = NotificationManager()    override init() {    notificationManager.registerObserver(MyNotificationItemAdded) { note in      println("item added!")    }        super.init()  }    required init(coder: NSCoder) {    fatalError("decoding not implemented")  }}
When the MyController instance is deallocated, its NotificationManager member variable will be automatically deallocated, triggering the call to deregisterAll that will remove the dead objects from NSNotificationCenter.
In my apps, I add a notificationManager instance to my common UIViewController base class so I don't have to explicitly declare the member variable in all of my controller subclasses.

Another benefit of using my own wrapper around NSNotificationCenter is that I can add useful functionality, like group observers: an observer that's triggered when any one of a group of notifications are posted:

struct NotificationGroup {  let entries: [String]    init(_ newEntries: String...) {    entries = newEntries  }
}
extension NotificationManager {  func registerGroupObserver(group: NotificationGroup, block: (NSNotification! -> ()?)) {    for name in group.entries {      registerObserver(name, block: block)    }  }}
This can be a great way to easily set up an event handler to run when, for example, an item is changed in any way at all:
   let MyNotificationItemsChanged = NotificationGroup(      MyNotificationItemAdded,      MyNotificationItemDeleted,      MyNotificationItemMoved,      MyNotificationItemEdited    )
    notificationManager.registerGroupObserver(MyNotificationItemsChanged) { note in      // ...    }
Categories: Offsite Blogs

Ivory Language

Haskell on Reddit - Wed, 08/27/2014 - 12:54am
Categories: Incoming News

A Face Only A Mother Could Love.

Haskell on Reddit - Tue, 08/26/2014 - 8:44pm
Categories: Incoming News

Simon Michael: Creating well-behaved Hakyll blog posts

Planet Haskell - Tue, 08/26/2014 - 8:15pm

Posts in a Hakyll-powered blog need to be created with care, if you want your feed to work well with clients and aggregators. There are many things to remember:

  • If you have clones of your site, decide which one to work in and make sure it’s up to date
  • Create the file in the right place
  • Name it consistently (I use YYYY-MM-DD-url-safe-title.md)
  • In my setup, prefix it with _ if it’s a draft (I render but don’t publish those)
  • Set title, tags, and author with a metadata block
  • Set published time with metadata to get a more precise timestamp than Hakyll can guess from the filename. Include a time zone. Use the right format.
  • When moving a post from draft to published:
    • Update the published time
    • Update the file name if the title or publish date has changed
  • If changing a post after it has been published: set updated time in the metadata
  • At some point, commit it to version control and sync it to other clones

I find this makes blogging feel tedious, especially after an absence when I’ve forgotten the details. Case in point, I managed to share an ugly template post with Planet Haskell readers while working on this one.

So I’m trying out this bash shell script, maybe it will help. Adjust to suit your setup.
(updated 2014/8/27)

# add to ~/.bashrc BLOGDIR=~/src/MYSITE.com/blog # List recent blog posts. alias blog-ls="ls $BLOGDIR | tail -10" # Create a new hakyll-compatible draft blog post. # blog-new ["The Title" ["tag1, tag2" ["Author Name"]]] function blog-new() { ( TITLE=${1:-Default Title} TAGS=${2:-defaulttag1, defaulttag2} AUTHOR=${3:-Default Author Name} SLUG=${TITLE// /-} DATE=`date +"%Y-%m-%d"` TIME=`date +"%Y-%m-%d %H:%M:%S%Z"` FILE=_$DATE-$SLUG.md echo creating $BLOGDIR/$FILE cat <<EOF >>$BLOGDIR/$FILE && emacsclient -n $BLOGDIR/$FILE --- title: $TITLE tags: $TAGS author: $AUTHOR published: $TIME --- EOF ) }

An example:

$ blog-new 'Scripted Hakyll blog post creation' 'hakyll, haskell' creating _2014-05-03-Scripted-Hakyll-blog-post-creation.md (file opens in emacs, edit & save) $ make ./site build Initialising... Creating store... Creating provider... Running rules... Checking for out-of-date items Compiling updated blog/_2014-05-03-Scripted-Hakyll-blog-post-creation.md Success

See also part 2.

Categories: Offsite Blogs

Simon Michael: Well-behaved Hakyll blog posts, continued

Planet Haskell - Tue, 08/26/2014 - 8:00pm

More hakyll blog fixes:

Ugly things showing on planets

My posts were showing unwanted things on planet haskell - double heading, redundant date, tag links, and ugly disqus html. By comparing with Jasper Van der Jeugt’s blog, I found the problem: I was snapshotting content for the feed at the wrong time, after applying the post template:

>>= return . fmap demoteHeaders >>= loadAndApplyTemplate "templates/post.html" (postCtx tags) >>= saveSnapshot "content" >>= loadAndApplyTemplate "templates/default.html" defaultContext

Better:

>>= saveSnapshot "content" -- >>= return . fmap demoteHeaders >>= loadAndApplyTemplate "templates/post.html" (postCtx tags) >>= loadAndApplyTemplate "templates/default.html" defaultContext

Manual feed publishing

The main blog feed is now generated with a _ prefix, and I must manually rename it (with make feed) to make it live it on Planet Haskell. This will hopefully reduce snafus (and not create new ones).

./site.hs 95 - create ["blog.xml"] $ do + create ["_blog.xml"] $ do ./Makefile 14 +feed: _site/blog.xml + +_site/blog.xml: _site/_blog.xml + cp _site/_blog.xml _site/blog.xml +

Better HTML titles

Changed the “Joyful Systems” prefix to a suffix in the HTML page titles, making search results and browser tab names more useful.

Categories: Offsite Blogs

What is the current streaming (pipes, conduit, iteratee etc.) IO solution?

Haskell on Reddit - Tue, 08/26/2014 - 7:46pm

I'm hoping for something "highlevel" like pipes or conduit, but I have no idea how they compare. The use-case is realtime streaming data from (for example) a sensor or network packets, doing something like filling a mutable vector, or running some image processing before sending a response. Does anyone know which implementations are the fastest? Are they all sufficient, or is there some better "hand rolled" way?

submitted by dogirardo
[link] [17 comments]
Categories: Incoming News