| CARVIEW |
Select Language
HTTP/2 200
date: Fri, 16 Jan 2026 00:11:10 GMT
server: Apache
last-modified: Sat, 10 Jan 2026 21:40:24 GMT
etag: "22819-6480f7d53efa7"
accept-ranges: bytes
content-type: application/xml
vary: Accept-Encoding
content-encoding: gzip
via: e14s
Codes on Brandon Simmons' website
https://brandon.si/code/
Recent content in Codes on Brandon Simmons' website
Hugo
en-us
Fri, 02 Jan 2026 22:34:34 -0500
-
Sandbox Minus John Dillinger Equals What?
https://brandon.si/code/sandbox-minus-john-dillinger/
Fri, 12 Dec 2025 18:43:03 -0500
https://brandon.si/code/sandbox-minus-john-dillinger/
<p><em>It didn’t look like anyone had ever tried to answer the
<a href="https://en.wikipedia.org/wiki/Trout_Fishing_in_America">question</a>,
so I thought I would have a go. This post probably won’t be interesting to
folks already familiar with embeddings or linear algebra. It represents my
rough, non-expert understanding of the subject matter</em></p>
<hr>
<p>Huh. What could it mean to subtract two words, and how
would you even do that? If we just consider the <em>how</em>, it’s not too hard to
come up with a scheme. You could map a word to its place in the dictionary,
say, then subtract the numbers and interpret the result <code>N</code> to mean the <code>Nth</code>
word. But that’s not interesting, because alphabetical order (the basis of our
mapping) is totally unrelated to a word’s <em>meaning</em>.</p>
-
Linking Smaller Haskell Binaries
https://brandon.si/code/linking-smaller-haskell-binaries/
Sat, 07 Jan 2023 15:52:00 -0500
https://brandon.si/code/linking-smaller-haskell-binaries/
<p>Haskell binaries can get quite large (think ~100MB), especially for projects
with many transitive dependencies. Here are two strategies that can help at
link time, the latter being more experimental.</p>
<p>I used the <code>test-pandoc</code> binary from <a href="https://github.com/jgm/pandoc">pandoc</a> on
GHC 9.2.5 below. This was nice because obviously it was easy to test if linking
broke anything (just run the tests).</p>
<h2 id="-split-sections-and---gc-sections"><code>-split-sections</code> and <code>--gc-sections</code></h2>
<p>You can instruct ghc to emit code in individual minimal sections, allowing the
linker to easily find and remove dead code. This looks like, in your
<code>cabal.project</code>:</p>
-
GHC LLVM LTO Experiments Scratch Notes
https://brandon.si/code/ghc-llvm-lto-experiments-scratch-notes/
Sun, 02 Jun 2019 00:00:00 +0000
https://brandon.si/code/ghc-llvm-lto-experiments-scratch-notes/
<p>*This is a followup to <a href="https://brandon.si/code/initial-hacking-of-ghc-for-gcc-link-time-optimization/">this previous post</a>
where I play with GCC’s link-time optimization in GHC-compiled programs. I note there that this is
limited since it only works on sources compiled from C (crucially the RTS). Here I’ve compiled rough
notes doing the same thing with LLVM LTO, where I attempt to get true whole-program optimization
*cooking.</p>
<p><em>The goals were to play with some new tech and possibly discover some significant performance gains
(without thinking very hard) that could be ported back or realized in a less hacky way.
Results were underwhelming and so I don’t do much real digging into assembly (the other thing
besides good results that would have made for an interesting post). So after waffling I decided to
basically dump my notes here, lightly edited, in case it’s helpful to someone who wants to take up
similar work later.</em></p>
-
A little tool for visualizing ghc verbose timing
https://brandon.si/code/a-little-tool-for-visualizing-ghc-verbose-timing/
Tue, 07 May 2019 00:00:00 +0000
https://brandon.si/code/a-little-tool-for-visualizing-ghc-verbose-timing/
<p>I wrote a little tool to graph the fine-grained timing logs produced by ghc
when the <code>-v</code> (verbose) flag is given. These logs to STDERR look like, e.g.</p>
<pre><code>!!! Liberate case [Data.Binary.Class]: finished in 32.06 milliseconds, allocated 14.879 megabytes
!!! Simplifier [Data.Binary.Class]: finished in 873.97 milliseconds, allocated 563.867 megabytes
</code></pre>
<p>The project is on GitHub at
<a href="https://github.com/jberryman/ghc-timing-treemap">jberryman/ghc-timing-treemap</a>,
along with a screenshot.</p>
<p>Navigating within the graph is pretty slow at least in firefox, and there are
some other improvements that could be made, for instance some of the phases are
run multiple times on the same module and it would be nice to see these
grouped, where the module name is logged.</p>
-
Initial hacking of GHC for GCC link-time optimization
https://brandon.si/code/initial-hacking-of-ghc-for-gcc-link-time-optimization/
Wed, 10 Apr 2019 00:00:00 +0000
https://brandon.si/code/initial-hacking-of-ghc-for-gcc-link-time-optimization/
<p>I spent some time hacking GHC to use GCC’s <a href="https://en.wikipedia.org/wiki/Interprocedural_optimization">link-time optimization</a>,
and wanted to share the results. The idea was to see whether we could get
performance gains or other interesting results from :</p>
<ul>
<li>cross module inlining, e.g. between C libraries from <code>base</code> and the RTS</li>
<li>GCC build flags that can only be added later, like <code>-march=native</code> to tailor optimizations to our microarchitecture</li>
<li>possibly nice interactions at barrier of haskell code and LTO’d C?</li>
</ul>
<p>This was all very speculative, and the results you see below aren’t ultimately
very interesting.</p>
-
Hacking around on an FV-1 based guitar pedal
https://brandon.si/code/hacking-around-on-an-fv-1-based-guitar-pedal/
Sat, 26 Jan 2019 00:00:00 +0000
https://brandon.si/code/hacking-around-on-an-fv-1-based-guitar-pedal/
<p><em>This is a diary-style post where I chronicle what I learn digging into a
digital guitar effects pedal for the first time. I’m not sure how useful or
interesting it will be to others.</em></p>
<hr>
<p>I picked up an oddball modulation pedal from a “boutique” maker (being coy here)
and decided there were a bunch of things I could improve about it, so I thought
I’d try to tweak it. I know almost nothing about electronics.</p>
-
Choosing a binary-to-text encoding
https://brandon.si/code/choosing-a-binary-to-text-encoding/
Sat, 22 Apr 2017 00:00:00 +0000
https://brandon.si/code/choosing-a-binary-to-text-encoding/
<p>I had an occasion to think about text-friendly binary encoding schemes for the
first time at work. The obvious choice is
<a href="https://en.wikipedia.org/wiki/Base64"><strong>Base64</strong></a>, but my immediate subsequent
thought was “there must be something much more efficient for our purposes”, and a quick google led
<a href="https://stackoverflow.com/questions/31817721/a-more-compact-representation-than-base64-for-byte-arrays">here</a>
in which OP echos the same feeling:</p>
<blockquote>
<p>It seems to me that we can greatly improve since on my keyboard I already see
94 easily distinguishable printable keys.</p>
-
Almost inline ASM in haskell with foreign import prim
https://brandon.si/code/almost-inline-asm-in-haskell-with-foreign-import-prim/
Sun, 12 Mar 2017 00:00:00 +0000
https://brandon.si/code/almost-inline-asm-in-haskell-with-foreign-import-prim/
<p>With help from Reid Barton in questions <a href="https://stackoverflow.com/q/41528208/176841">here</a> and
<a href="https://stackoverflow.com/q/41213378/176841">here</a> I discovered it’s pretty
easy to call assembly from GHC haskell with minimal overhead, so I cleaned up
an example of this technique and posted it here:</p>
<p><a href="https://github.com/jberryman/almost-inline-asm-haskell-example">https://github.com/jberryman/almost-inline-asm-haskell-example</a></p>
<p>This is especially useful if you want to return multiple values from a foreign
procedure, where otherwise with the traditional FFI approach you would have to
do some allocation and stuff the values into a struct or something. I find the
above more understandable in any case.</p>
-
Announcing: unagi-bloomfilter
https://brandon.si/code/announcing-unagi-bloomfilter/
Thu, 25 Aug 2016 00:00:00 +0000
https://brandon.si/code/announcing-unagi-bloomfilter/
<p>I just released a new Haskell library called unagi-bloomfilter that is up now
<a href="https://hackage.haskell.org/package/unagi-bloomfilter">on hackage</a>. You can
install it with:</p>
<pre><code>$ cabal install unagi-bloomfilter
</code></pre>
<p>The library uses the <em>bloom-1</em> variant from “Fast Bloom Filters and Their
Generalization” by Yan Qiao, et al. I’ll try to write more about it when I have
the time. Also I just gave a talk on things I learned working on the project
last night at the New York Haskell User Group:</p>
-
Announcing: Hashabler 1.0. Now even more hashy with SipHash
https://brandon.si/code/announcing-hashabler-1-dot-0-now-even-more-hashy-with-siphash/
Sun, 16 Aug 2015 00:00:00 +0000
https://brandon.si/code/announcing-hashabler-1-dot-0-now-even-more-hashy-with-siphash/
<p>I’ve just released version 1.0 of a haskell library for principled,
cross-platform & extensible hashing of types. It is available
<a href="https://hackage.haskell.org/package/hashabler">on hackage</a>, and can be
installed with:</p>
<pre><code>cabal install hashabler
</code></pre>
<p>(see my <a href="https://brandon.si/code/announcing-hashabler-like-hashable/">initial announcement post</a>
which has some motivation and pretty pictures)</p>
<p>You can see the <a href="https://github.com/jberryman/hashabler/blob/master/CHANGELOG.markdown">CHANGELOG</a>
but the main change is an implementation of <a href="https://131002.net/siphash/">SipHash</a>.
It’s about as fast as our implementation of FNV-1a for bytestrings of length
fifty and slightly faster when you get to length 1000 or so, so you should use
it unless you’re wanting a hash with a simple implementation.</p>
-
Translating some stateful bit-twiddling to haskell
https://brandon.si/code/translating-some-stateful-bit-twiddling-to-haskell/
Fri, 03 Jul 2015 00:00:00 +0000
https://brandon.si/code/translating-some-stateful-bit-twiddling-to-haskell/
<p>I just started implementing <a href="https://131002.net/siphash/">SipHash</a> in
<a href="https://hackage.haskell.org/package/hashabler"><code>hashabler</code></a> and wanted to share
a nice way I found to translate stateful bit-twiddling code in C (which makes
heavy use of bitwise assignment operators) to haskell.</p>
<p>I was working from the
<a href="https://github.com/veorq/SipHash/blob/master/siphash24.c">reference implementation</a>.
As you can see statefulness and mutability are an implicit part of how the
algorithm is defined, as it modifies the states of the <code>v</code> variables.</p>
<pre><code>#define SIPROUND \
do { \
v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
v2 += v3; v3=ROTL(v3,16); v3 ^= v2; \
v0 += v3; v3=ROTL(v3,21); v3 ^= v0; \
v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
} while(0)
int siphash( uint8_t *out, const uint8_t *in, uint64_t inlen, const uint8_t *k )
{
/* ... */
for ( ; in != end; in += 8 )
{
m = U8TO64_LE( in );
v3 ^= m;
TRACE;
for( i=0; i<cROUNDS; ++i ) SIPROUND;
v0 ^= m;
}
</code></pre>
<p>I wanted to translate this sort of code as directly as possible (I’d already
decided if it didn’t work on the first try I would burn my laptop and live in
the woods, rather than debug this crap).</p>
-
Announcing hashabler: like hashable only more so
https://brandon.si/code/announcing-hashabler-like-hashable/
Thu, 30 Apr 2015 00:00:00 +0000
https://brandon.si/code/announcing-hashabler-like-hashable/
<p>I’ve just released the first version of a haskell library for principled,
cross-platform & extensible hashing of types, which includes an implementation
of the FNV-1a algorithm. It is available <a href="https://hackage.haskell.org/package/hashabler">on hackage</a>,
and can be installed with:</p>
<pre><code>cabal install hashabler
</code></pre>
<p><code>hashabler</code> is a rewrite of the <a href="https://hackage.haskell.org/package/hashable">hashable</a>
library by Milan Straka and Johan Tibell, having the following goals:</p>
<ul>
<li>
<p>Extensibility; it should be easy to implement a new hashing algorithm on any
Hashable type, for instance if one needed more hash bits</p>
-
Benchmarking very fast things with criterion
https://brandon.si/code/benchmarking-very-fast-things-with-criterion/
Thu, 05 Mar 2015 00:00:00 +0000
https://brandon.si/code/benchmarking-very-fast-things-with-criterion/
<p>There’s a pervasive myth that Bryan O’Sullivan’s excellent haskell benchmarking
library <a href="https://hackage.haskell.org/package/criterion">criterion</a> is only
useful for benchmarks that take some significant chunk of time (I’ve even heard
some people claim on the <em>ms</em> scale). In fact criterion is useful for almost
anything you’d want to benchmark.</p>
<p>At a high level <code>criterion</code> makes your benchmark the inner loop of a function,
and runs that loop a bunch of times, measures the result, and then divides by
the number of iterations it performed. The approach is both useful for comparing
alternative implementations, and probably the only meaningful way of answering
“how long does this code take to run”, short of looking at the assembly and
counting the instructions and consulting your processor’s manual.</p>
-
Announcing unagi-chan
https://brandon.si/code/announcing-unagi-chan/
Tue, 07 Oct 2014 00:00:00 +0000
https://brandon.si/code/announcing-unagi-chan/
<p>Today I released version 0.2 of <code>unagi-chan</code>, a haskell library implementing
fast and scalable FIFO queues with a nice and familiar API. It is
<a href="https://hackage.haskell.org/package/unagi-chan">available on hackage</a>
and you can install it with:</p>
<pre><code>$ cabal install unagi-chan
</code></pre>
<p>This version provides a bounded queue variant (and closes
<a href="https://github.com/jberryman/unagi-chan/issues/1">issue #1</a>!)
that has performance on par with the other variants in the library. This is
something I’m somewhat proud of, considering that the standard
<a href="https://hackage.haskell.org/package/stm-2.4.3/docs/Control-Concurrent-STM-TBQueue.html"><code>TBQueue</code></a>
is not only significantly slower than e.g. <code>TQueue</code>, but also was seen to
livelock at a fairly low level of concurrency (and so is not included in the
benchmark suite).</p>
-
Thoughts on FIFO-ness
https://brandon.si/code/thoughts-on-fifo-ness/
Mon, 03 Feb 2014 00:00:00 +0000
https://brandon.si/code/thoughts-on-fifo-ness/
<p>I’ve been doing a lot of experimenting with concurrent operations in haskell
and in particular playing with and thinking about the design of concurrent
<a href="https://en.wikipedia.org/wiki/Queue_%28abstract_data_type%29">FIFO queues</a>.
These structures are difficult to make both efficient and correct,
due to the effects of contention on the parts of the structure tasked with
coordinating reads and writes from multiple threads.</p>
<p>These are my thoughts so far on FIFO semantics.</p>
<h2 id="fifo-and-how">FIFO? And how!</h2>
<p>In the interesting paper
<a href="https://www.cs.uni-salzburg.at/~hpayer/publications/races12.pdf">“How FIFO is your concurrent FIFO queue?”</a>(PDF).
A Haas, et al. propose that an ideal FIFO queue has operations that are
instantaneous (think of each <code>write</code> having an infinitely accurate timestamp,
and each <code>read</code> taking the corresponding element in timestamp order). They then
measure the degree to which <em>real</em> queues of various designs deviate from this
platonic FIFO semantics in their message ordering, using a metric they call
“element-fairness”. They experimentally measure element-fairness of both
so-called “strict FIFO” as well as “relaxed FIFO” designs, in which elements
are read in more or less the order they were written (some providing guarantees
of degree of re-ordering, others not).</p>
-
Announcing shapely-data v0.1
https://brandon.si/code/announcing-shapely-data-v0-dot-1/
Mon, 23 Dec 2013 00:00:00 +0000
https://brandon.si/code/announcing-shapely-data-v0-dot-1/
<p>This is the first <em>real</em> release <code>shapely-data</code>, a haskell library
<a href="https://hackage.haskell.org/package/shapely-data">up here on hackage</a>
for working with algebraic datatypes in a simple generic form made up of
haskell’s primitive product, sum and unit types: <code>(,)</code>, <code>Either</code>, and <code>()</code>.</p>
<p>You can install it with</p>
<pre><code>cabal install shapely-data
</code></pre>
<h1 id="motivation-and-examples">Motivation and examples</h1>
<p>In order from most to least important to me, here are the concerns that
motivated the library:</p>
<ul>
<li>
<p>Provide a good story for <code>(,)</code>/<code>Either</code> as a <em>lingua franca</em> generic
representation that other library writers can use without dependencies,
encouraging abstractions in terms of products and sums (motivated
specifically by my work on
<a href="https://hackage.haskell.org/package/simple-actors"><code>simple-actors</code></a>.</p>
-
Writing a streaming twitter waterflow solution
https://brandon.si/code/writing-a-streaming-twitter-waterflow-solution/
Mon, 18 Nov 2013 00:00:00 +0000
https://brandon.si/code/writing-a-streaming-twitter-waterflow-solution/
<p>In <a href="https://philipnilsson.github.io/Badness10k/articles/waterflow/">this post</a>
Philip Nilsson describes an inspiring, principled approach to solving
a toy problem posed in a programming interview. I wanted to implement a
solution to a variant of the problem where we’d like to process a stream.
It was pretty easy to sketch a solution out on paper but Philip’s solution
was invaluable in testing and debugging my implementation. (See also Chris
Done’s <a href="https://chrisdone.com/posts/twitter-problem-loeb">mind-melting loeb approach</a>)</p>
<p>My goal was to have a function:</p>
-
A TypeFamilies Primer
https://brandon.si/code/a-typefamilies-primer/
Mon, 12 Aug 2013 00:00:00 +0000
https://brandon.si/code/a-typefamilies-primer/
<p><code>TypeFamilies</code> is a GHC extension that lets you create formerly-impossible
abstractions in a very straightforward way. It took me several tries before
they clicked for me though, so this is the introduction to <code>TypeFamilies</code> that
I wish I had read first (although I just found <a href="https://byorgey.wordpress.com/2010/07/06/typed-type-level-programming-in-haskell-part-ii-type-families/">Brent Yorgey’s</a>, which would have done the trick).</p>
<p>I’m treating the subject very narrowly for most of this post, and try to round
things out a little at the very end.</p>
-
Thinking about an economy of bit flips
https://brandon.si/code/thinking-about-an-economy-of-bit-flips/
Sun, 17 Mar 2013 00:00:00 +0000
https://brandon.si/code/thinking-about-an-economy-of-bit-flips/
<p><em>Disclaimer: un-researched, under-educated, fast and loose hacking follows.</em></p>
<hr>
<p>The other day I was thinking about counting in binary and how bits cascade when
incrementing a counter.</p>
<pre><code>000
001
010
011
100
</code></pre>
<p>I wondered: what if each bit flip was very “expensive”, for the hardware say?
Are there other methods we could use that woud result in a “cheaper” increment
operation, by avoiding those costly carries?</p>
<p>First, here’s a little bit of boring code that we’ll use below to print a list
of Ints as padded binary, and some requisite imports:</p>
-
Using GHC's RebindableSyntax for a dynamic state "Fauxnad"
https://brandon.si/code/using-ghcs-rebindablesyntax-for-a-dynamic-state-fauxnad/
Sun, 10 Feb 2013 00:00:00 +0000
https://brandon.si/code/using-ghcs-rebindablesyntax-for-a-dynamic-state-fauxnad/
<p>I just learned about GHC’s <code>RebindableSyntax</code> extension from
<a href="https://www.reddit.com/r/haskell/comments/16zrsp/generalizing_do_notation/">chrisdoner’s thread on reddit</a>
and wanted to play around with scratching a couple itches I’ve had. In this
post I’ll illustrate using <code>RebindableSyntax</code> to allow us to use haskell’s
<code>do</code> notation in a State-monad-like construction, in which our state type is
allowed to change (I’ve played with this idea
<a href="https://brandon.si/code/a-state-monad-with-dynamically-typed-state/">previously</a>).</p>
<p>The dynamic state construction looks like the traditional <code>State</code>, but with
separate types for input and output state:</p>
-
dilly.js: a library for loops with delays in JavaScript
https://brandon.si/code/dilly-dot-js-a-library-for-loops-with-delays-in-javascript/
Tue, 09 Oct 2012 00:00:00 +0000
https://brandon.si/code/dilly-dot-js-a-library-for-loops-with-delays-in-javascript/
<p>I’ve released a <a href="https://github.com/jberryman/dilly.js">new library</a>
for writing sort of idiomatic-looking loops with delays in javascript. This was
motivated by <a href="https://jberryman.github.com/fly-mis/">this</a>
work in which I was implementing an algorithm/simulation;
I wanted the code to be readable as straighforward loops, but I needed
a delay for the visual portion.</p>
<p>Here is an example of its usage:</p>
<pre><code>withDelay(1000).endingWith(other_stuff)
.for("x",1,2) // range: 1, 2
.for("y",1,3 , 8) // range(with step of 2): 1, 3, 5, 7
.for("z",['a','b']) // foreach: 'a', 'b'
.do(function(){
console.log(this.var("x"),
this.var("y"),
this.var("z"));
});
</code></pre>
<p>The inner <code>do</code> block runs with a one-second delay between executions.</p>
-
Making your zipper disappear with Zippo
https://brandon.si/code/making-your-zipper-disappear-with-zippo/
Mon, 17 Sep 2012 00:00:00 +0000
https://brandon.si/code/making-your-zipper-disappear-with-zippo/
<p>I’ve finally had a chance to look at how my new lens-based, power-packed,
minimal zipper library <a href="https://hackage.haskell.org/package/zippo-0.1">zippo</a>
looks when compiled, and initial results are pleasing!</p>
<p>For example, here is a silly zipper operation that increments the nodes
of a sort-of tree:</p>
<pre><code>module Main where
import Control.Category((>>>))
import Data.Lens.Zipper
import Data.Yall.Lens
data Tree a = Br { _lBranch :: NodeBr a
, _rBranch :: NodeBr a }
deriving Show
data NodeBr a = NodeBr { _node :: a }
deriving Show
-- START BOILERPLATE
lBranch = lens _lBranch (\(Br _ r) l-> Br l r)
rBranch = lens _rBranch (\(Br l _) r-> Br l r)
node = lens _node $ const NodeBr
-- END BOILERPLATE
-- example data:
t = Br (NodeBr 1 ) (NodeBr 3 )
-- zipper operations
incNode = moveP node >>> modf (+1) >>> moveUp
zops = zipper >>> moveP lBranch >>> incNode >>> moveUp >>>
moveP rBranch >>> incNode >>> close
main = print $ zops t
</code></pre>
<p>When compiled with</p>
-
simple-actors 0.4.0: a few interesting design bits
https://brandon.si/code/simple-actors-0-dot-4-0-a-few-interesting-design-bits/
Wed, 22 Aug 2012 00:00:00 +0000
https://brandon.si/code/simple-actors-0-dot-4-0-a-few-interesting-design-bits/
<p><a href="https://hackage.haskell.org/package/simple-actors">simple-actors</a>
is my library for more structured concurrent programming based
on the <a href="https://en.wikipedia.org/wiki/Actor_model">Actor model</a>.
It’s been a fun vehicle for exploring concurrent
semantics, and an opportunity to solve some tricky API design problems in
pretty clever ways. I want to present a handful of these problems, and the
solutions I came up with, below.</p>
<p><em>Short digression:</em> I love distributed systems, but this library has nothing to
do with distributed programming. Also performance.</p>
-
zippo: a lightweight lens-based, type-checked, heterogenous zipper
https://brandon.si/code/zippo/
Mon, 28 May 2012 00:00:00 +0000
https://brandon.si/code/zippo/
<p>I finished this new <a href="https://hackage.haskell.org/package/zippo">zipper library</a>
which you can get with a</p>
<pre><code>cabal install zippo
</code></pre>
<p>and <a href="https://github.com/jberryman/zippo">fork it on github</a>.</p>
<p>After working for a long time on <a href="https://hackage.haskell.org/package/pez">pez</a>,
I wanted to try a zipper library that was also based on lenses, but where
heterogenous move up operations would be type-checked, as would a move up
past the “top” of the structure.</p>
<p>It looks as though <a href="https://hackage.haskell.org/package/instant-zipper">instant-zipper</a>
is the only other zipper package that provides that kind of type safety.</p>
-
A Simulation of a Biological MIS Algorithm
https://brandon.si/code/a-simulation-of-a-biological-mis-algorithm/
Mon, 14 May 2012 00:00:00 +0000
https://brandon.si/code/a-simulation-of-a-biological-mis-algorithm/
<p>I’ve finished a simulation-visualization of the very cool algorithm for
generating a
<a href="https://en.wikipedia.org/wiki/Maximal_independent_set">Maximal Independant Set</a>
from “A Biological Solution to a Fundamental Distributed Computing Problem” by
Afek et al. (sorry I don’t have a link to the PDF, and respect you too much to
link you to a paywall).</p>
<p>You can <a href="https://jberryman.github.com/fly-mis/">play with it</a>
or <a href="https://github.com/jberryman/fly-mis">check out the code</a> on GitHub;
in particular, see
<a href="https://github.com/jberryman/fly-mis/blob/master/algorithm.js">“algorithm.js”</a>
for the didactic implementation of the algorithm.</p>
<p>It uses jQuery and <a href="https://raphaeljs.com">Raphael.js</a> for the visuals and
events.</p>
-
Converting HTML5 canvas elements to images
https://brandon.si/code/converting-html5-canvas-elements-to-images/
Mon, 30 Apr 2012 00:00:00 +0000
https://brandon.si/code/converting-html5-canvas-elements-to-images/
<p>I recently needed to do some conversions/processing to a bunch of HTML files,
which contained html <a href="https://en.wikipedia.org/wiki/Canvas_element">canvas</a>
images, so I needed a way of converting all the canvas elements on the page to
PNGs.</p>
<p>After a bit of research and tweaking, the following worked well enough for me:</p>
<p>{% gist 2561736 %}</p>
<p>Run it in your browser’s JS console on the page you want to process (we assume
jQuery is already loaded on the page).</p>
-
Announcing yet another lens library
https://brandon.si/code/yall/
Wed, 04 Apr 2012 00:00:00 +0000
https://brandon.si/code/yall/
<p>I just uploaded the first version of a lens library I’ve been working on, called
<a href="https://hackage.haskell.org/package/yall">yall</a>. You can get it with a</p>
<pre><code>cabal install yall
</code></pre>
<p>or check it out <a href="https://github.com/jberryman/yall">on github</a>. There will be a
Template Haskell library for automatically deriving lenses at some point in the
future.</p>
<p>I was motivated primarily by the desire for a lens that is acceptable for
<a href="https://hackage.haskell.org/package/pez">pez</a> (existing libs such as the
excellent <a href="https://hackage.haskell.org/package/fclabels">fclabels</a>
or <a href="https://hackage.haskell.org/package/data-lens">data-lens</a>
didn’t fit the bill for assorted reasons), and
to explore some abstractions and generalizations re lenses more deeply.</p>
-
the Monoid instance for Ordering
https://brandon.si/code/the-monoid-instance-for-ordering/
Mon, 02 Apr 2012 00:00:00 +0000
https://brandon.si/code/the-monoid-instance-for-ordering/
<p>I was just looking at the <a href="https://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Monoid.html">Monoid</a>
docs, when I found an instance that surprised me: <code>Ordering</code>.</p>
<p>Here is how it’s defined:</p>
<pre tabindex="0"><code>-- lexicographical ordering
instance Monoid Ordering where
mempty = EQ
LT `mappend` _ = LT
EQ `mappend` y = y
GT `mappend` _ = GT
</code></pre><p>Without the comment I don’t know if I would have gotten it right away, but
check this out:</p>
<pre><code>Prelude> :m + Data.Monoid
Prelude Data.Monoid> zipWith compare "asff" "asdf"
[EQ,EQ,GT,EQ]
Prelude Data.Monoid> let compare' s = mconcat . zipWith compare s
Prelude Data.Monoid> compare' "asff" "asdf"
GT
</code></pre>
<p>A string comparison function can be defined using the comparisons of
corresponding letters (, numbers, etc.) as Monoids.</p>
-
Optimization fun: Minimum Edit Distance
https://brandon.si/code/optimization-fun-minimum-edit-distance/
Tue, 20 Mar 2012 00:00:00 +0000
https://brandon.si/code/optimization-fun-minimum-edit-distance/
<p>I’m doing Stanford’s free online [NLP class](NLP class),
and last week’s lesson introduced
<a href="https://en.wikipedia.org/wiki/Levenshtein_distance">Levenshtein Distance</a>
and the traditional matrix-based algorithm. I implemented
the algorithm in haskell to get a better understanding of it, but then got a bit
obsessive about optimizing.</p>
<p>I wanted to develop an approach iteratively so I’d learn something along the way,
but I didn’t take great pains to document the process very well, nor do I have any
analysis here of low level details.</p>
-
shapely-data: a library for structuralizing Haskell data types
https://brandon.si/code/shapely-data/
Tue, 06 Mar 2012 00:00:00 +0000
https://brandon.si/code/shapely-data/
<p>This was a quick, on-a-whim sort of project that ended up taking me all week,
as I learned my way around
<a href="https://www.haskell.org/ghc/docs/7.0.2/html/users_guide/template-haskell.html">template haskell</a>.
It felt like trying to make a sandwich with your feet for the first time, and
was about as traumatizing.</p>
<p>Anyway the result is my library named
<a href="https://hackage.haskell.org/package/shapely-data">shapely-data</a>
which you can get with the usual…</p>
<pre><code>cabal install shapely-data
</code></pre>
<p>and is up on github <a href="https://github.com/jberryman/shapely-data">here</a>.</p>
<p>The library can be used to convert an algebraic data type into a form that
replaces its constructors with a combination of <code>(,)</code>, <code>Either</code> and <code>()</code>. See
the haddocks for usage information, and implementation details.</p>
-
Categories that want to be Arrows
https://brandon.si/code/categories-that-want-to-be-arrows/
Sat, 11 Feb 2012 00:00:00 +0000
https://brandon.si/code/categories-that-want-to-be-arrows/
<p>This is me recording some half-formed thoughts that have been rattling around
in my head for the last week. They concern haskell’s
<a href="https://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Arrow.html">Arrow</a>
typeclass; in particular it’s frustrating inability to be applied to types that
are in <a href="https://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Category.html">Category</a>
but have no suitable implementation for <code>arr</code>.</p>
<p>Consider something as simple as:</p>
<pre><code>newtype Bij a b = Bij (a -> b) (b -> a)
</code></pre>
<p>a <code>Category</code> instance is trivial, but an <code>Arrow</code> instance is impossible, since
we would need to supply a <code>b -> a</code> given only a <code>a -> b</code>.</p>
-
How the Haskell Prelude avoids overlapping instances in Show
https://brandon.si/code/how-the-haskell-prelude-avoids-overlapping-types-in-show/
Mon, 06 Feb 2012 00:00:00 +0000
https://brandon.si/code/how-the-haskell-prelude-avoids-overlapping-types-in-show/
<p>In reading about overlapping instances in haskell, I came across <a href="https://hackage.haskell.org/trac/haskell-prime/wiki/OverlappingInstances">this</a>
proposal that mentioned that:</p>
<blockquote>
<p>[Overlapping types] can sometimes be simulated with the extra-method trick
used in the Show class of the Prelude for showing lists of characters
differently than lists of other things.</p>
</blockquote>
<p>I’d never thought about how haskell-98 can support a <code>show "asdf"</code> that returns</p>
<pre><code>"\"asdf\""
</code></pre>
<p>while <code>show [1,2,3,4]</code> returns</p>
<pre><code>"[1,2,3,4]"
</code></pre>
<p>And I was surprised at the complexity of <code>Show</code> when I looked at the <a href="https://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#t:Show">docs</a> and
implementation (to be honest, I had no idea how the class was implemented or
that <code>show</code> was not the only method).</p>
-
Haskell state of the Lens, etc.
https://brandon.si/code/haskell-state-of-the-lens/
Tue, 31 Jan 2012 00:00:00 +0000
https://brandon.si/code/haskell-state-of-the-lens/
<p>For my own purposes, I wanted to take a tour of all the various formulations of
lenses on hackage and thought I would post the lightly-curated results here. I
just grepped the package list page for the following terms: lens, label,
record, accessor, editor, and reference. Some were not sufficiently general to
include here.</p>
<p>Here were the ones implementing “lens-like” functionality, loosely in order of
my opinion on their usefulness for my own purposes:</p>
-
pez v0.1.0 released
https://brandon.si/code/pez-v0-dot-1-0-released/
Sun, 29 Jan 2012 00:00:00 +0000
https://brandon.si/code/pez-v0-dot-1-0-released/
<p><a href="https://hackage.haskell.org/packages/archive/pez/0.1.0/doc/html/Data-Label-Zipper.html">pez</a>
is a powerful, generic zipper library that can be used with a minimum of
boilerplate, using <a href="https://hackage.haskell.org/package/fclabels">fclabels</a>
lenses as an interface. This new version supports fclabels 1.0 and uses the new
lenses supporting failure.</p>
<p>The API has changed significantly, but should be more stable at this point. You
can try it with a:</p>
<pre><code>$ cabal install pez
</code></pre>
<p>You can find the code on github <a href="https://github.com/jberryman/pez">here</a>. I
will try to post some fun examples here in the next week or two.</p>
-
simple-actors 0.1.0 released
https://brandon.si/code/simple-actors-0-1-0-released/
Tue, 11 Oct 2011 00:00:00 +0000
https://brandon.si/code/simple-actors-0-1-0-released/
<p>Just a quick announcement of the release of
<a href="https://hackage.haskell.org/packages/archive/simple-actors/0.1.0/doc/html/Control-Concurrent-Actors.html">simple-actors</a>,
a DSL-style haskell
library for more structured concurrent programs via the
<a href="https://en.wikipedia.org/wiki/Actor_model">Actor Model</a>. You can fork it on
<a href="https://github.com/jberryman/simple-actors">github</a>, and install it via cabal
with a</p>
<pre><code>cabal install simple-actors
</code></pre>
<p>This version is significantly more coherent, powerful and simple than the
original 0.0.1 version (which was something I just whipped together for a blog
post I haven’t gotten around to writing yet).</p>
<p>Let me know if you have any comments or suggestions!</p>
-
A brief tutorial-introduction to 'fclabels' 1.0
https://brandon.si/code/a-brief-tutorial-introduction-to-fclabels-1-0/
Sun, 21 Aug 2011 00:00:00 +0000
https://brandon.si/code/a-brief-tutorial-introduction-to-fclabels-1-0/
<p>Sebastiaan Visser et al. last week announced the release of v1.0 of
<a href="https://hackage.haskell.org/package/fclabels">fclabels</a>. This is a short
introduction to the changes for people who are already somewhat familiar with
the package.</p>
<blockquote>
<p><strong>Que?</strong> The fclabels package is a haskell library providing “first class
labels” for haskell data types and some Template Haskell code for
automatically generating said labels. This makes for a more composable and
much more powerful alternative to haskell’s built-in record syntactic sugar.
<a href="https://blog.ezyang.com/2010/04/inessential-guide-to-fclabels/">Here</a> is a
good introductory tutorial.</p>
-
Module 'chan-split' released
https://brandon.si/code/module-chan-split-released/
Sun, 17 Jul 2011 00:00:00 +0000
https://brandon.si/code/module-chan-split-released/
<h2 id="whaa">Whaa?</h2>
<p>chan-split is a haskell library that is a wrapper around
<a href="https://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Concurrent-Chan.html"><code>Control.Concurrent.Chan</code></a>s
that separates a Chan into a readable side and
a writable side.</p>
<p>We also provide two other modules: <code>Data.Cofunctor</code> (because there didn’t seem
to be one anywhere), and <code>Control.Concurrent.Chan.Class</code>. The latter creates
two classes: <code>ReadableChan</code> and <code>WritableChan</code>, making the fundamental chan
functions polymorphic, and defining an instance for standard <code>Chan</code> as well as
<code>MVar</code> (an MVar is a singleton bounded channel, wanna fight about it?).</p>
-
simple-actors: a simple Actor Model concurrency library
https://brandon.si/code/simple-actors-a-simple-actor-model-concurrency-library/
Mon, 30 May 2011 00:00:00 +0000
https://brandon.si/code/simple-actors-a-simple-actor-model-concurrency-library/
<blockquote>
<p><strong>EDIT:</strong> I’ve just released
<a href="https://hackage.haskell.org/packages/archive/simple-actors/0.1.0/doc/html/Control-Concurrent-Actors.html">version 0.1.0</a>
of this library. It is a
complete re-write / re-think that I think makes the library much more
attractive, simple and powerful. There won’t be any more dramatic API changes.</p>
</blockquote>
<p>I was in need of a simple, tight library implementing the
<a href="https://en.wikipedia.org/wiki/Actor_model">Actor Model of concurrency</a> and didn’t find one on
hackage, so I wrote my own. You can check out the docs
<a href="https://hackage.haskell.org/package/simple-actors-0.0.1">here</a> and get it with
a</p>
-
Magic Haskell code completions in Vim!
https://brandon.si/code/magic-haskell-code-completions-in-vim/
Sat, 07 May 2011 00:00:00 +0000
https://brandon.si/code/magic-haskell-code-completions-in-vim/
<blockquote>
<p><strong>UPDATE</strong>: This project is on hold for now. Many people have pointed out
that the snipMate VIM plugin can probably handle many of these completions. I
may make a collection of those at some point, but I no longer have much
interest in finishing this.</p>
</blockquote>
<p>I’m trying something new: putting code-in-progress up on github while I work
on it. So! I love haskell so freaking much I’ve started creating a vimscript
to improve the <em>typeability</em> of the language in the vim editor, and the
working name is:
<a href="https://github.com/jberryman/haskomplete.vim">haskomplete.vim</a></p>
-
PEZ: the Potentially-Excellent Zipper library release
https://brandon.si/code/pez-zipper-library-released/
Tue, 19 Apr 2011 00:00:00 +0000
https://brandon.si/code/pez-zipper-library-released/
<p>I’m happy to announce the release of a
<a href="https://hackage.haskell.org/package/pez">zipper library I named<strong>PEZ</strong></a>! I’ve been learning and
building this silly library almost as long as I’ve been learning haskell. It’s
not as great as it could be, but I’m releasing it now because it’s about time.</p>
<p>You can check it out with a:</p>
<blockquote>
<p><code>cabal install pez</code></p>
</blockquote>
<p>The library provides a generic
<a href="https://www.haskell.org/haskellwiki/Zipper">zipper</a> that can be used on all
types in the Typeable class, for which the user defines (or generates) lenses
from the excellent <a href="https://hackage.haskell.org/package/fclabels">fclabels</a>
package.</p>
-
Synchronized Concurrent IO Actions
https://brandon.si/code/synchronized-concurrent-io-actions/
Thu, 24 Feb 2011 00:00:00 +0000
https://brandon.si/code/synchronized-concurrent-io-actions/
<p>This is a bit of literate haskell code that works through a system for
running concurrent IO computations that are synchronized on a stream. So we
have many “nodes” of the type <code>:: a -> IO ()</code> running concurrently on a single
stream, where we would like each node to wait until all nodes have processed a
stream element before any are allowed to proceed onto the next element.</p>
<p>This was motivated by the desire to simulate a system in which many nodes are
interacting independently according to a time-synchronized algorithm. So the
“stream” the nodes process is time.</p>
-
When is it okay to 'fail'?
https://brandon.si/code/when-is-it-okay-to-fail/
Wed, 16 Feb 2011 00:00:00 +0000
https://brandon.si/code/when-is-it-okay-to-fail/
<p>That’s the question.</p>
<p>In designing a couple libraries the question of the proper use of the <code>Monad</code>
class’s <code>fail</code> method has come up more than once.</p>
<p>On the one hand, many people consider <code>fail</code> to be a wart on the face of an
otherwise pure implementation of an elegant construction
<a href="https://en.wikipedia.org/wiki/Monad_%28category_theory%29">borrowed from category theory</a>.
It’s as if someone defined scissors as</p>
<blockquote>
<p>“two metal blades with handles, attached by a pivot… plus a bandaid in
case you cut yourself”.</p>
-
New version of directory-tree on hackage
https://brandon.si/code/new-version-of-directory-tree-on-hackage/
Sun, 13 Feb 2011 00:00:00 +0000
https://brandon.si/code/new-version-of-directory-tree-on-hackage/
<p>In response to a request and my own review I’ve modified my
<a href="https://hackage.haskell.org/package/directory-tree">directory-tree</a> package as follows:</p>
<ul>
<li>
<p>Eq and Ord instances now compare on free “contents” type variable</p>
</li>
<li>
<p>we provide <code>equalShape</code> function for comparison of shape and filenames
of arbitrary trees (ignoring free “contents” variable)</p>
</li>
<li>
<p>provide a comparingShape used in sortDirShape</p>
</li>
<li>
<p>provide a <code>sortDirShape</code> function that sorts a tree, taking into account
the free file “contents” data</p>
</li>
</ul>
<p>Now that equality and comparison functions that ignore the contents of Files
are out of the Eq and Ord instances, we can make those types of comparisons on
DirTrees of different types.</p>
-
Do Applicative Functors generalize the S & K Combinators?
https://brandon.si/code/do-applicative-functors-generalize-the-s-k-combinators/
Sun, 02 Jan 2011 00:00:00 +0000
https://brandon.si/code/do-applicative-functors-generalize-the-s-k-combinators/
<p>If the title hasn’t scared you off yet, here’s the story: I was hacking on
someone else’s <a href="https://hackage.haskell.org/package/fclabels-0.11.1.1">code</a> on
the plane and trying to wrap my head around some
<a href="https://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Applicative.html#t:Applicative"><code>Applicative</code> class</a>
code; in particular the code in
question used the Applicative instance for <code>((->) a)</code> i.e. functions. This
turned my brain to cream-of-wheat and I had to take a break.</p>
<p>If you aren’t familiar with <strong>Applicative Functors</strong>, they are somewhere in
between the familiar and simple <code>Functor</code> class and the <code>Monad</code> class; an
abstraction for function application with a context. Check out
<a href="https://www.haskell.org/haskellwiki/Applicative_functor">here</a> for more. Away
from the computer I got out a pad of paper and went about trying to figure out
how the <code><*></code> method was defined over functions. Here are the types:</p>
-
Working with Template Haskell in GHCi
https://brandon.si/code/working-with-template-haskell-in-ghci/
Tue, 14 Dec 2010 00:00:00 +0000
https://brandon.si/code/working-with-template-haskell-in-ghci/
<p>I’ve just started trying to learn and debug
<a href="https://www.haskell.org/haskellwiki/Template_Haskell">Template Haskell</a> and found it a
bit rough trying to explore TH interactively, but a couple of things have
helped.</p>
<p>First and most obvious, we can use runQ to see the abstract TH syntax which a
quasi-quoted expression expands to:</p>
<pre><code>Prelude> :set -XTemplateHaskell
Prelude> :m + Language.Haskell.TH
Prelude Language.Haskell.TH> runQ [| \a -> a+1 |]
LamE [VarP a_1] (InfixE (Just (VarE a_1)) (VarE GHC.Num.+) (Just (LitE (IntegerL 1))))
</code></pre>
<p>The second thing that was really helpful to me was turning on the <em>dump-
splices</em> debugging option which causes GHC to print the expansions of all
<code>$(top-level splices)</code>:</p>
-
A State Monad with dynamically-typed state
https://brandon.si/code/a-state-monad-with-dynamically-typed-state/
Thu, 09 Dec 2010 00:00:00 +0000
https://brandon.si/code/a-state-monad-with-dynamically-typed-state/
<p>Haskell’s
<a href="https://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Monad-State-Lazy.html">standard State monad types</a> allow the programmer to define a computation
that works with some state in a way that looks and feels similar to using
mutable state in an imperative language. However these State monad types are
limited in that <em>the type of the state cannot change</em> during the computation.</p>
<p>Normally this is fine, but what if we really wanted to use the mechanics of a
state monad to pass some state value that changed type, e.g. some mutually-
recursive tree structure we would like to traverse?:</p>
-
New version of 'thrist' package released
https://brandon.si/code/new-version-of-thrist-package-released/
Sat, 13 Nov 2010 00:00:00 +0000
https://brandon.si/code/new-version-of-thrist-package-released/
<p>I’ve been collaborating with Gabor Greif on a
<a href="https://hackage.haskell.org/package/thrist">new version of his ’thrist’ module</a>,
which was just released
last night! I approached Gabor with some new ideas that came to me as I was
writing a module that uses Thrists heavily, and he invited me to co-author
this version. (See below for a brief explanation of Thrists).</p>
<p>I noticed that in the previous version, the function <code>foldThrist</code> was
essentially a <code>foldr</code> with a type signature that was overly restrictive.</p>
-
Designing a Module for Combinatory Logic in Haskell
https://brandon.si/code/designing-a-module-for-combinatory-logic-in-haskell/
Sat, 04 Sep 2010 00:00:00 +0000
https://brandon.si/code/designing-a-module-for-combinatory-logic-in-haskell/
<p>Like the <a href="https://en.wikipedia.org/wiki/Lambda_calculus">Lambda Calculus</a> (on
which Lisp is based), Combinatory Logic is a formal system that can be used to
model and study computation. What makes it fascinating is that it is as
powerful as the (already simple) lambda calculus, but has no need for the
variables that LC requires to perform substitution!</p>
<p>Here I show how we can use Haskell’s type classes and other language features
to model the Combinator Calculus. The goals of this module were:</p>
-
Repairing NetbookInstaller's Chameleon Bootloader
https://brandon.si/code/repairing-netbookinstallers-chameleon-bootloader/
Fri, 27 Aug 2010 00:00:00 +0000
https://brandon.si/code/repairing-netbookinstallers-chameleon-bootloader/
<p>If you have set up your hackintosh using Meklort’s
<a href="https://code.google.com/p/netbook-installer/">NetbookBootMaker / NetbookInstaller</a> and have
overwritten the Chameleon bootloader with
<a href="https://www.gnu.org/software/grub/">GRUB</a> or have otherwise damaged your MBR,
you can use some of the following techniques to fix your issues.</p>
<p>NetbookInstaller uses a custom version of
<a href="https://chameleon.osx86.hu/">Chameleon</a> to patch the Mac OS kernel in memory
during bootup. If you have accidentally installed GRUB (or another bootloader)
to your MBR, you will probably find it is impossible to boot into your OS X
partition.</p>
-
17x17: some Simulated Annealing updates
https://brandon.si/code/17x17-some-simulated-annealing-updates/
Sat, 31 Jul 2010 00:00:00 +0000
https://brandon.si/code/17x17-some-simulated-annealing-updates/
<p>Note: this is part of a
<a href="https://brandon.si/tags/17x17/">series of posts</a> is related to the
“<a href="https://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17x17 Challenge</a>”
posted by Bill Gasarch. The goal is to color
cells of a 17 by 17 grid, using only four colors, such that no rectangle is
formed from four cells of the same color.</p>
<hr>
<p>Just a few follow-ups to my previous
<a href="https://brandon.si/code/17x17-a-simulated-annealing-approach-using-thresholds/">post in which I use a simulated annealing-type algorithm</a> to find a good (hopefully
complete) cover of a grid by swapping rows and columns from four identical
sub-grids of 74 colors.</p>
-
The Gift of Inconsistency
https://brandon.si/code/the-gift-of-inconsistency/
Thu, 22 Jul 2010 00:00:00 +0000
https://brandon.si/code/the-gift-of-inconsistency/
<p>Computer science is a fascinating and maddening thing. Even the most
seemingly-esoteric topics turn out to be fundamental. Go out to the fringes of
CS and you find yourself smack in the middle of
<a href="https://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems#Minds_and_machines">Philosophy</a>. You
try to understand a single point and you suddenly find yourself embracing
everything.</p>
<p>So this post comes from that infinitely-recursive rabbit hole of wikipedia
topics I’ve been falling down for the last few weeks, and you can probably
expect a few more like this one; I’ll try to keep focused.</p>
-
17x17: A Simulated Annealing approach using thresholds
https://brandon.si/code/17x17-a-simulated-annealing-approach-using-thresholds/
Sat, 10 Jul 2010 00:00:00 +0000
https://brandon.si/code/17x17-a-simulated-annealing-approach-using-thresholds/
<p>Note: this is part of a
<a href="https://brandon.si/tags/17x17/">series of posts</a> is related to the
“<a href="https://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17x17 Challenge</a>”
posted by Bill Gasarch. The goal is to color
cells of a 17 by 17 grid, using only four colors, such that no rectangle is
formed from four cells of the same color.</p>
<hr>
<p>This is something I’ve been wanting to play with for months now, but haven’t
made the time to implement: I wondered if
<a href="https://en.wikipedia.org/wiki/Simulated_annealing">simulated annealing</a> techniques could
be effective in finding a complete grid covering.</p>
-
17x17: Further Thoughts & Some Pretty Pictures
https://brandon.si/code/17x17-further-thoughts-some-pretty-pictures/
Tue, 01 Jun 2010 00:00:00 +0000
https://brandon.si/code/17x17-further-thoughts-some-pretty-pictures/
<p>Note: this is part of a
<a href="https://brandon.si/tags/17x17/">series of posts</a> is related to the
“<a href="https://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17x17 Challenge</a>”
posted by Bill Gasarch. The goal is to color
cells of a 17 by 17 grid, using only four colors, such that no rectangle is
formed from four cells of the same color.</p>
<hr>
<p>An almost silly amount of time passes between my new ideas on this problem and
investigating/coding those ideas, but I’m trying to be better about helping my
thoughts see the light of day before I get entirely bored of them.</p>
-
Befunge-93 Interpreter on Hackage
https://brandon.si/code/befunge-93-interpreter-on-hackage/
Thu, 20 May 2010 00:00:00 +0000
https://brandon.si/code/befunge-93-interpreter-on-hackage/
<p>I’ve fixed a bug related to upgrading GHC to version 6.12 (thanks to Cale and
the folks on haskell-cafe who helped me with the issue) and got my
<a href="https://en.wikipedia.org/wiki/Befunge">Befunge-93</a> interpreter up on hackage.
The program is written in haskell (as usual). You should be able to get it
soon with a:</p>
<pre><code>$ cabal install Befunge93
</code></pre>
<p>If you want to read about how I designed it you can check out the source
above, or take a look at my
<a href="https://brandon.si/code/a-befunge-93-interpreter/">previous blog post</a>.</p>
-
Code Jam 2010: Incrementing a Binary Counter
https://brandon.si/code/code-jam-2010-incrementing-a-binary-counter/
Sun, 09 May 2010 00:00:00 +0000
https://brandon.si/code/code-jam-2010-incrementing-a-binary-counter/
<h3 id="the-problem">The Problem</h3>
<p><a href="https://code.google.com/codejam/contest/dashboard?c=433101#s=p0">Problem A</a> in
the qualifying round of this year’s Google CodeJam contest was really clever.
The problem used a classic made-for-TV gadget from the 80s:
<a href="https://www.youtube.com/watch?v=-XUOhjW2AXM">The Clapper™</a> (“snapper” in google’s
version) and went like this:</p>
<blockquote>
<p>The Snapper is a clever little device that, on one side, plugs its input
plug into an output socket, and, on the other side, exposes an output socket
for plugging in a light or other device.</p>
-
17x17: Some Attempts at Doubly-Symmetrical Rotations
https://brandon.si/code/17x17-some-attempts-at-doubly-symmetrical-rotations/
Fri, 09 Apr 2010 00:00:00 +0000
https://brandon.si/code/17x17-some-attempts-at-doubly-symmetrical-rotations/
<p>Note: this is part of a
<a href="https://brandon.si/tags/17x17/">series of posts</a> is related to the "
<a href="https://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17x17 Challenge</a>"
posted by Bill Gasarch. The goal is to color
cells of a 17 by 17 grid, using only four colors, such that no rectangle is
formed from four cells of the same color.</p>
<hr>
<p>In a <a href="https://brandon.si/code/17x17-symmetric-single-colorings-and-some-graph-theory/">previous post</a>
I presented rotations of some single-color rectangle-free grids which were symmetrical along a diagonal axis. I
also noticed that, of the single-colorings of optimal size which I could
generate, all with an odd number side-length could be made symmetrical along
<em>both</em> diagonals (the evens could not):</p>
-
Lazy Arithmetic in Haskell
https://brandon.si/code/lazy-arithmetic-in-haskell/
Wed, 24 Mar 2010 00:00:00 +0000
https://brandon.si/code/lazy-arithmetic-in-haskell/
<p>We don’t usually give much thought to Numeric data types beyond whether we
want to work with integers or decimal numbers. And that is a shame! In this
post I’ll look at how we can actually do arithmetic operations lazily, and in
the process hopefully reveal a bit about haskell’s numeric classes.</p>
<pre><code>module LazyArithmetic
where
</code></pre>
<p>We will be using
<a href="https://hackage.haskell.org/package/numbers-2009.8.9">Lennart Augustsson’s <code>numbers</code> library</a> which can be
installed from hackage with
<a href="https://hackage.haskell.org/trac/hackage/wiki/CabalInstall">cabal-install</a>:</p>
-
17x17: More about symmetry and a new rotation
https://brandon.si/code/17x17-more-about-symmetry-and-a-new-rotation/
Thu, 18 Mar 2010 00:00:00 +0000
https://brandon.si/code/17x17-more-about-symmetry-and-a-new-rotation/
<p>This is part of a
<a href="https://brandon.si/tags/17x17/">series of posts</a> is related to the "
<a href="https://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17x17 Challenge</a>"
posted by Bill Gasarch. The goal is to color
cells of a 17 by 17 grid, using only four colors, such that no rectangle is
formed from four cells of the same color.</p>
<hr>
<p>In my <a href="https://brandon.si/code/17x17-symmetric-single-colorings-and-some-graph-theory/">last post</a>,
I gave a symmetrical rotation of the known 74-cell single-coloring. I want to
use a slight variation of that grid to show why I think treating the grids as
symmetrical will help us in solving this problem.</p>
-
17x17: Symmetric Single-Colorings and some Graph Theory
https://brandon.si/code/17x17-symmetric-single-colorings-and-some-graph-theory/
Sun, 14 Mar 2010 00:00:00 +0000
https://brandon.si/code/17x17-symmetric-single-colorings-and-some-graph-theory/
<p>This is part of a
<a href="https://brandon.si/tags/17x17/">series of posts</a> is related to the
“<a href="https://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17x17 Challenge</a>”
posted by Bill Gasarch. The goal is to color
cells of a 17 by 17 grid, using only four colors, such that no rectangle is
formed from four cells of the same color.</p>
<p>In my <a href="https://brandon.si/code/17x17-some-thoughts-on-the-problem/">last post</a>
I noticed that all of the smaller optimal single-colorings I
generated showed diagonal symmetry, meaning that row 1 is the same as column
1, row 8 is the same as column 8, etc. It’s my hypothesis that all complete
single-colorings are symmetrical in this way.</p>
-
17x17: Some Thoughts on the Problem
https://brandon.si/code/17x17-some-thoughts-on-the-problem/
Sun, 07 Mar 2010 00:00:00 +0000
https://brandon.si/code/17x17-some-thoughts-on-the-problem/
<p>I’ve been puzzling over some of the problems presented by the
<a href="https://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17 x 17 Challenge</a>, and wanted to share some of what I’ve learned
and have been wondering about. The problem and ultimate goal is to color a 17
x 17 grid with four colors such that every cell is colored and no rectangle is
formed by any four cells of the same color.</p>
<h2 id="single-color-subsets">Single-Color Subsets</h2>
<p>I’ve started by trying to find an algorithm to find optimal single-color
subsets, i.e. a way of coloring a grid with one color such that no rectangle
is formed by the colored cells, and we have the greatest number of cells
colored as possible. I started thinking of coloring cells one at a time,
following a path based on the notion of an “extended rectangle” where the
fourth side was longer or shorter than the first, to avoid forming rectangles.</p>
-
17x17: Deterministic algorithm for single-coloring a grid
https://brandon.si/code/17x17-deterministic-algorithm-for-single-coloring-a-grid/
Mon, 01 Mar 2010 00:00:00 +0000
https://brandon.si/code/17x17-deterministic-algorithm-for-single-coloring-a-grid/
<p>I finally got some time to code up a messy script to test out a few
variations of an algorithm to generate rectangle-free single colorings of a
grid, as part of a <del>lazy</del> humble effort to solve the
<a href="https://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17 x 17 challenge</a>.</p>
<p>This post is going to be a bit of a code-dump. The algorithm is essentially:</p>
<ol>
<li>
<p>color cell,</p>
</li>
<li>
<p>turn to the right,</p>
</li>
<li>
<p>stop on first non-rectangle forming cell,</p>
</li>
<li>
<p>if the cell is uncolored, color it and turn to the right, else if the cell was already colored and has been entered from this direction already, then skip it, else turn to the right</p>
-
17x17: Brute Force Algorithm for an Optimal Rectangle-Free Subset
https://brandon.si/code/17x17-brute-force-algorithm-for-an-optimal-rectangle-free-subset/
Tue, 23 Feb 2010 00:00:00 +0000
https://brandon.si/code/17x17-brute-force-algorithm-for-an-optimal-rectangle-free-subset/
<p>I’ve been making notes when I have time, on the
<a href="https://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">“17 x 17 challenge”</a>
posted a couple months back by Bill Gasarch. I’ve been
sketching out algorithms for the problem and wanted to quickly produce some
optimal rectangle free subsets to check my work and look at. So the code below
answers the following question:</p>
<blockquote>
<p>Imagine an n x n grid. You can color cells of the grid such that no
rectangle overlayed on the grid will have all four corners colored. Find a
grid with the maximum possible colored cells.</p>
-
An alternative definition for Data.List.groupBy
https://brandon.si/code/an-alternative-definition-for-datalistgroupby/
Wed, 10 Feb 2010 00:00:00 +0000
https://brandon.si/code/an-alternative-definition-for-datalistgroupby/
<p>The function
<a href="https://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-List.html#v:groupBy"><code>groupBy</code></a> from haskell’s standard library is defined in terms
of <code>span</code>, the effect being that the supplied predicate function is used to
compare the first element of a group with successive elements.</p>
<p>This isn’t clear from the docs, and you might try to do this and wonder at the
output you got:</p>
<pre><code>*Main> groupBy (< =) [3,4,5,3,2,1,4,4,1,1,2,3,4,5,4,5,6,7]
[[3,4,5,3],[2],[1,4,4,1,1,2,3,4,5,4,5,6,7]]
</code></pre>
<p>We can redefine <code>groupBy</code> as follows, so that the supplied predicate function
compares adjacent elements one-by-one and returns <code>True</code> if they should be
grouped together:</p>
-
The Definition of Data.List.group
https://brandon.si/code/the-definition-of-datalistgroup/
Sat, 06 Feb 2010 00:00:00 +0000
https://brandon.si/code/the-definition-of-datalistgroup/
<p>I’ve been thinking quite a bit lately about a category of functions that are
always a bit awkward to define: they involve cases where we would like to
traverse a recursive data structure and do something with the data that we
have passed over but which is “gone now”. There are many examples of
functions like these in the haskell standard libraries:
<code>[span](https://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/src/GHC-List.html#span)</code>,
<code>[splitAt](https://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/src/GHC-List.html#splitAt)</code>, etc.</p>
<p>A function like <code>group</code> is in this category. It’s conceptually very simple,
but defining it actually requires a bit of indirection. Here I’ve translated
the definition from <code>Data.List</code> to use explicit recursion:</p>
-
A Befunge-93 Interpreter
https://brandon.si/code/a-befunge-93-interpreter/
Sun, 31 Jan 2010 00:00:00 +0000
https://brandon.si/code/a-befunge-93-interpreter/
<p>I just finished an initial release of an interpreter for the
<a href="https://en.wikipedia.org/wiki/Befunge">befunge</a> programming language, based on
the <a href="https://catseye.tc/projects/befunge93/">‘93 spec</a>. The project was quite
fun! My goal was to produce a well-designed program with performance that
didn’t suck too bad. Here are some highlights:</p>
<h2 id="design">Design</h2>
<p>I found that writing the core functionality of the interpreter took almost no
time, once I settled on the approach I would take. I used a monad transformer
for the first time, <code>StateT</code>:</p>
-
DeBruijn Sequences pt.3 - The "Prefer Opposite" algorithm
https://brandon.si/code/debruijn-sequences-pt3-the-prefer-opposite-algorithm/
Wed, 02 Dec 2009 00:00:00 +0000
https://brandon.si/code/debruijn-sequences-pt3-the-prefer-opposite-algorithm/
<p>This is the third post of mine on DeBruijn sequences, and is in preparation
for another post to come which I hope should be an interesting investigation
into a possible parallel algorithm. The first two posts are
<a href="https://brandon.si/code/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/">here</a> and
<a href="https://brandon.si/code/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/">here</a>.</p>
<hr>
<p>This algorithm works identically to the Prefer One algorithm, however
rather than choose a 1-bit if possible, we instead choose the opposite
bit from the previous bit, if possible.</p>
<p>This has the effect of evening out the locations of the zeros and ones
throughout the sequence. We will exploit this in a later post where I
will explore a possible parallel algorithm, which should be interesting
I hope!</p>
-
Find a permutation given its Inversion Table
https://brandon.si/code/find-a-permutation-given-its-inversion-table/
Sun, 15 Nov 2009 00:00:00 +0000
https://brandon.si/code/find-a-permutation-given-its-inversion-table/
<p>Here is some code I whipped up in response to an
<a href="https://www.reddit.com/r/coding/comments/a3ckw/programming_problem_find_a_permutation_given_its/">interesting problem posted on reddit.com/r/coding/</a>. It was a really interesting
algorithm to work out:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-haskell" data-lang="haskell"><span style="display:flex;"><span><span style="color:#66d9ef">import</span> Data.List (<span style="color:#a6e22e">sortBy</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">-- takes an inversion list and converts it to the list of permuted </span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">-- elements: </span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">decode</span> <span style="color:#f92672">=</span> dec <span style="color:#66d9ef">[]</span> <span style="color:#f92672">.</span> sortBy lowHi <span style="color:#f92672">.</span> zip [<span style="color:#ae81ff">1</span><span style="color:#f92672">..</span>] <span style="color:#66d9ef">where</span>
</span></span><span style="display:flex;"><span> dec as <span style="color:#66d9ef">[]</span> <span style="color:#f92672">=</span> as
</span></span><span style="display:flex;"><span> dec as ((a,<span style="color:#66d9ef">_</span>)<span style="color:#66d9ef">:</span>is) <span style="color:#f92672">=</span> <span style="color:#66d9ef">let</span> is' <span style="color:#f92672">=</span> sortBy lowHi (decrementGT a is)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">in</span> dec (a<span style="color:#66d9ef">:</span>as) is'
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">-- decrement every inversion number by 1, for every tuple in which </span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">-- the element is greater than `a`: </span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">decrementGT</span> a <span style="color:#f92672">=</span> map (<span style="color:#a6e22e">\</span>(a',i) <span style="color:#f92672">-></span> (a', <span style="color:#66d9ef">if</span> a'<span style="color:#f92672">></span>a <span style="color:#66d9ef">then</span> i<span style="color:#f92672">-</span><span style="color:#ae81ff">1</span> <span style="color:#66d9ef">else</span> i) )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">-- we sort by the inversion number, low to high. For elements with </span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">-- the same inversion number, we say that the greater element tuple </span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">-- should go before a lesser element: </span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">lowHi</span> (a,i) (a',i')
</span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> i <span style="color:#f92672">==</span> i' <span style="color:#f92672">=</span> <span style="color:#66d9ef">if</span> a<span style="color:#f92672">></span>a' <span style="color:#66d9ef">then</span> <span style="color:#66d9ef">LT</span> <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">GT</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> otherwise <span style="color:#f92672">=</span> compare i i'
</span></span></code></pre></div><p>It’s not the prettiest code I’ve written, but it’s pretty straight-forward and
concise. Thanks for looking!</p>
-
An "Adaptive" Move-to-Front Algorithm
https://brandon.si/code/an-adaptive-move-to-front-algorithm/
Fri, 13 Nov 2009 00:00:00 +0000
https://brandon.si/code/an-adaptive-move-to-front-algorithm/
<p><strong>UPDATE:</strong> Thanks to <a href="https://smj.posterous.com/">steve</a> for pointing out that the scheme I describe here is essentially the same as <a href="https://www.ics.uci.edu/~dan/pubs/DC-Sec5.html#Sec_5.2">Algorithm BSTW</a>.</p>
<p>I came up with this variation of the
<a href="https://brandon.si/code/the-move-to-front-mtf-transform/">Move-to-Front transform</a>
which doesn’t require that there be a known alphabet of symbols.
Instead it builds up the alphabet as it goes along and encounters a new
symbol. I’m sure that this is a known algorithm, as it’s a fairly obvious
variation, but I don’t know what the proper name for it is, so I’m calling it
an <a href="https://www.cs.sfu.ca/CC/365/li/squeeze/AdaptiveHuff.html">Adaptive</a> Move-
to-Front.</p>
-
The move-to-front (MTF) Transform
https://brandon.si/code/the-move-to-front-mtf-transform/
Tue, 10 Nov 2009 00:00:00 +0000
https://brandon.si/code/the-move-to-front-mtf-transform/
<p>To follow up my last <a href="https://brandon.si/code/polishing-a-functional-pearl-the-burrows-wheeler-transform/">post about the Burrows-Wheeler Transform</a>,
I decided to implement another simple
algorithm which is often used after the BWT to help consolidate localized
redundancy in the data before entropy encoding.</p>
<p>The idea behind the <a href="https://www.data-compression.info/Algorithms/MTF/index.htm">Move-to-Front algorithm</a> is that we start with some known
alphabet (like the list of ASCII characters), and encode our data elements as
the <em>index into that alphabet list</em> of each element. The trick is that after
each character is encoded, the alphabet list is modified by <strong>moving</strong> the
element whose index we just looked up <strong>to the front</strong> of the alphabet.</p>
-
Polishing a Functional Pearl: The Burrows-Wheeler Transform
https://brandon.si/code/polishing-a-functional-pearl-the-burrows-wheeler-transform/
Sat, 07 Nov 2009 00:00:00 +0000
https://brandon.si/code/polishing-a-functional-pearl-the-burrows-wheeler-transform/
<p>Here is a quick post to get me back into the swing of blogging.</p>
<p>I was looking through an old post on StackOverflow about
<a href="https://www.haskell.org/haskellwiki/Research_papers/Functional_pearls">clever functional code</a>,
and the best answer, given by
<a href="https://stackoverflow.com/questions/1524750/what-is-your-favourite-cleverly-written-functional-code/1527026#1527026">“yairchu”</a> was a nice version of the
<a href="https://en.wikipedia.org/wiki/Burrows%E2%80%93Wheeler%5Ftransform">Burrows-Wheeler Transform</a>,
which is an algorithm for permuting a string such that it can be compressed
more effectively by other algorithms. The code posted was (import Data.List
assumed):</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-haskell" data-lang="haskell"><span style="display:flex;"><span><span style="color:#a6e22e">bwp</span> <span style="color:#f92672">::</span> (<span style="color:#66d9ef">Ord</span> a)<span style="color:#f92672">=></span> [a] <span style="color:#f92672">-></span> [a]
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">bwp</span> xs <span style="color:#f92672">=</span> map snd <span style="color:#f92672">$</span> sort <span style="color:#f92672">$</span> zip (rots xs) (rrot xs)
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">rots</span> xs <span style="color:#f92672">=</span> take (length xs) (iterate lrot xs)
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">lrot</span> xs <span style="color:#f92672">=</span> tail xs <span style="color:#f92672">++</span> [head xs]
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">rrot</span> xs <span style="color:#f92672">=</span> last xs <span style="color:#66d9ef">:</span> init xs
</span></span></code></pre></div><p>I saw I could improve/shorten this in a couple of obvious ways and came up
with this:</p>
-
The State Monad: a tutorial for the confused?
https://brandon.si/code/the-state-monad-a-tutorial-for-the-confused/
Sat, 24 Oct 2009 00:00:00 +0000
https://brandon.si/code/the-state-monad-a-tutorial-for-the-confused/
<p>I’ve written this <del>brief</del> tutorial on haskell’s <code>State</code> monad to
help bridge some of the elusive gaps that I encountered in other explanations
I’ve read, and to try to cut through all the sticky abstraction. This is
written for someone who has a good understanding of the <code>Maybe</code> and <code>List</code>
monads, but has gotten stuck trying to understand State. I hope it’s helpful!</p>
<h2 id="the-data-declaration">The Data Declaration:</h2>
<p>To understand a monad you look at its datatype and then at the definition for
bind (<code>>>=</code>). Most monad tutorials start by showing you the data declaration
of a <code>State s a</code> in passing, as if it needed no explanation:</p>
-
Cracking a Lock in Haskell with the De Bruijn sequence, pt. 2
https://brandon.si/code/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/
Tue, 29 Sep 2009 00:00:00 +0000
https://brandon.si/code/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/
<p>For this post I will rework the
<a href="https://brandon.si/code/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/">Prefer One algorithm from the previous post</a>
so that it is much more efficient. We will add
words to a <a href="https://en.wikipedia.org/wiki/Patricia_tree">Patricia Tree</a>-like
dictionary as we see them, passing the tree along in the State monad; to check
if a new word has been seen we simply check in the tree, rather than in the
array.</p>
<p>First, a little boilerplate…</p>
<pre tabindex="0"><code class="language-lhs" data-lang="lhs">> module Main
> where
>
> import Data.Array
> import Data.List(isInfixOf, tails)
>
> import Control.Monad.State
> import Control.Arrow
</code></pre><h3 id="new-implementation">NEW IMPLEMENTATION:</h3>
<p>In the previous implementation, to check if the word formed by adding a one
has been seen, we had to iterate through each of the previous bits in the
array, checking words.</p>
-
Cracking a Lock in Haskell with the De Bruijn sequence, pt. 1
https://brandon.si/code/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/
Thu, 24 Sep 2009 00:00:00 +0000
https://brandon.si/code/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/
<p>date = “a”
slug = “a/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1”
<a href="https://brandon.si/code/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/">Part 2</a>.</p>
<p>A <a href="https://en.wikipedia.org/wiki/De_Bruijn_sequence">De Bruijn sequence</a> is
(for example) a cyclical list of characters such that every word of a given
length appears once and only once in the sequence. Instead of using letters,
you can have a De Bruijn sequence of bits. For example here is one possibility
for a sequence in which every 3-bit word appears somewhere (you have to wrap
around from the end for the final “words”):</p>
-
Proposed modification to 'array' function in Data.Array
https://brandon.si/code/proposed-modification-to-array-function-in-dataarray/
Tue, 22 Sep 2009 00:00:00 +0000
https://brandon.si/code/proposed-modification-to-array-function-in-dataarray/
<p>In Data.Array the function <code>array :: (IArray a e, Ix i) => (i, i) -> [(i, e)] -> a i e</code> takes the array bounds and an association list, and it produces an
<code>Array</code>. The function allows you to build an Array by providing the elements
in whatever order you choose, rather than from the first index to the last.</p>
<p>The function <code>listArray</code> is similar except that it assumes that the list is
already ordered by index so there is no need to provide tuples of (index,
value). Becase <code>listArray</code> actually uses <code>zip</code> internally to produce the
tupled list, so the programmer can pass a list to <code>listArray</code> which <em>exceeds
the declared bounds of the array</em> and the function will quietly drop the extra
list tail:</p>
-
Some Haskell Boilerplate For Google CodeJam
https://brandon.si/code/haskell-boilerplate-for-google-codejam/
Sat, 22 Aug 2009 00:00:00 +0000
https://brandon.si/code/haskell-boilerplate-for-google-codejam/
<p>I put together a skeleton module which should be usable for any of the
problems in this year’s
<a href="https://code.google.com/codejam/">Google CodeJam Programming Contest</a> (as long as they don’t adopt a new
format/pattern for the problems this year). The module includes some useful
parsing functions which should in the worst case be useful as a cheatsheet for
those not too experienced with
<a href="https://legacy.cs.uu.nl/daan/download/parsec/parsec.html">Parsec</a> (*cough me).
I hope it will encourage people to
<a href="https://code.google.com/codejam/contest/registration">sign up</a> and use Haskell in
the contest!</p>
-
List Grouping module released
https://brandon.si/code/list-grouping-module-released/
Fri, 14 Aug 2009 00:00:00 +0000
https://brandon.si/code/list-grouping-module-released/
<p><strong>EDIT:</strong> Don’t use this package, but use instead
<a href="https://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html">Data.List.Split</a> by Brent Yorgey. I didn’t see that a package like his existed! This module will hopefully be removed from hackage if they can do that.</p>
<p>I just finished the initial release of a simple module called
<a href="https://hackage.haskell.org/package/list-grouping">list-grouping</a> that contains
functions to partition a list into sub-lists in various ways, based on some
predicate or integer offset. Functions like these are a little awkward to
write and I was surprised when I didn’t see anything on hackage!</p>
-
Enumerating all n-integer Sets Which Sum to an Integer x
https://brandon.si/code/enumerating-all-n-integer-sets-which-sum-to-an-integer-x/
Thu, 30 Jul 2009 00:00:00 +0000
https://brandon.si/code/enumerating-all-n-integer-sets-which-sum-to-an-integer-x/
<p>I came up with what I think is an elegant use of monadic code, while working
on a program to compute solutions to the
<a href="https://en.wikipedia.org/wiki/Postage_stamp_problem">Postage Stamp Problem</a>.
The problem asks:</p>
<blockquote>
<p>Consider that an envelope is able to hold a limited number of postage
stamps. Then, consider the set of the values of the stamps – positive
integers only. Then, what is the smallest total postage which <em>cannot</em> be put
onto the envelope?</p>
-
Fun with Lazy Arrays: the LZ77 Algorithm
https://brandon.si/code/fun-with-lazy-arrays-the-lz77-algorithm/
Thu, 18 Jun 2009 00:00:00 +0000
https://brandon.si/code/fun-with-lazy-arrays-the-lz77-algorithm/
<p>This is my third post investigating compression techniques related to the
DEFLATE algorithm: the first on
<a href="https://brandon.si/code/run-length-encoding/">run-length encoding</a>, and
the second on simple
<a href="https://brandon.si/code/huffman-coding/">Huffman Coding</a>.
This post models the
<a href="https://www.zlib.net/feldspar.html">LZ77 algorithm, the second of the two compression strategies used by DEFLATE</a>,
and in the process explores some interesting properties of Haskell’s basic
Arrays.</p>
<h3 id="implementation">Implementation:</h3>
<pre tabindex="0"><code class="language-lhs" data-lang="lhs">> module LZ77
> where
we will use GHC's "basic non-strict arrays" for this
experiment:
> import Data.Array
and use Ints to store the length of the entire decoded
message (needed to create our array):
> type Length = Int
> type Offset = Int
in place of the length in the standard length-offset pair
I've decided to use an Int representing the index of the
last element in the span relative to the element at
offset. Thus the pair encoding a span of only one element,
two elements back would be (0,2), rather than the more
traditional (1,2).
This simply makes more sense to me, especially since I want
to be able to encoded reversed sequences, as you will see.
> type Index = Int
and a few simple dataypes for our uncompressed and
compressed data respectively:
> type Decoded a = Array Index a
>
> data Encoded a = Enc Length [ Either a (Index,Offset) ]
The decompress function works by traversing the encoded message,
keeping track of our array index position (since offsets are
relative to the current position), and building an Array lazily
from a list which we generate, in part by referencing elements
from the partially generated array itself.
So when we see a Right value we look up in the Array the elements
referenced by the length-offset, concat-ing that list with the
result of processing the rest of the encoded message.
If we hit [] in 'dec' we call an error because the stored value
for the length of the uncompressed message in the Encoded type
was longer than what the 'decompress' function could produce.
It's diffficult to describe, but I hope the code is clear:
> decompress :: Encoded a -> Decoded a
> decompress (Enc el es) = decoded
> where decoded = listArray (0,el - 1) $ dec 0 es
> dec _ [] = error "message is shorter than it should be"
> dec n (Left x : xs) = x : dec (n+1) xs
> dec n (Right (iRel,off) : xs) =
> let i1 = n - off
> i2 = (if iN > i1 then succ else pred) i1
> iN = i1 + iRel
> in [ decoded!i | i <- [i1, i2 .. iN] ] ++ dec (n + 1 + abs iRel) xs
</code></pre><p>Some interesting things about the code above:</p>
-
Huffman Coding
https://brandon.si/code/huffman-coding/
Sun, 31 May 2009 00:00:00 +0000
https://brandon.si/code/huffman-coding/
<p>This is the second of probably three posts (the first was on
<a href="https://brandon.si/code/run-length-encoding/">run-length encoding in Haskell</a>)
inspired by Thomas Guest’s interesting
<a href="https://wordaligned.org/articles/deflate-runlength-encoding-but-better">article on the Deflate algorithm</a>.
This is also my first post in literate haskell. Please post any
improvements to the code if you have them!
For a refreshingly readable introduction to
<a href="https://en.wikipedia.org/wiki/Huffman_coding">Huffman Coding</a>
and the Deflate algorithm,
<a href="https://www.zlib.net/feldspar.html">have a look at this short explanation by Antaeus Feldspar</a>.</p>
<p>First some boilerplate…</p>
<pre tabindex="0"><code class="language-lhs" data-lang="lhs">> module Huffman
> where
> import Data.List (sort, insert)
> import qualified Data.Map as M
> import Data.Function (on)
> import Control.Arrow (second)
We make an abstract datatype for binary digits. I wonder if this would
be a nice (but slow?) way of working with binary IO. There doesn't seem
to be a package on Hackage for this
> data Bit = O | I
> deriving (Show, Ord, Eq)
we define a simple binary tree useful for decoding the encoded binary
stream. the simple algorithm for assigning codes to our symbols
produces this tree. A completed tree for some text containing only
three letter might look like this:
0 /\ 1
/\ A
C B
> data HTree a = Branch {zer :: (HTree a),
> one :: (HTree a),
> wt :: Int }
> | Leaf {symb :: a, wt :: Int }
> deriving (Show)
maps from <Symbol> to <Binary Code>, we create this from the HTree
built from the list of weighted symbols. the HTree can't be used for
encoding.
> type CodeDict a = M.Map a [Bit]
Now some instance declarations so that we know how to order (by weight):
> instance Ord (HTree a) where
> compare = compare `on` wt
>
> instance Eq (HTree a) where
> (==) = (==) `on` wt
our function for merging two branches which we use to build the HTree
from the list of symbols and their corresponding weights. no point in
defining a Monoid instance, but we'll tip our hat to it:
> mappend t1 t2 = Branch t1 t2 (wt t1 + wt t2)
</code></pre><h3 id="building-the-coding-trees">Building the Coding Trees</h3>
<pre tabindex="0"><code class="language-lhs" data-lang="lhs">We assign codes to our weighted symbols using a simple algorithm
which takes the trees (initially Leaves) with the lowest weights
and combines them (and their weights) and inserts them back into
the list until they have been combined into a single tree:
> buildDecTree :: [(a,Int)] -> HTree a
> buildDecTree = build . sort . map (uncurry Leaf)
> where build (t:[]) = t
> build (t1:t2:ts) = build $ insert (t1 `mappend` t2) ts
now convert the binary tree representation to a dictionary form for
encoding. we decompose the tree into a list from the top down, mapping
either a 1 or 0 over the flattened children. a little confusing:
> buildEncDict :: (Ord a) => HTree a -> CodeDict a
> buildEncDict = M.fromList . build
> where build (Leaf t _) = (t,[]) : []
> build (Branch a b _) = mapBit O a ++ mapBit I b
> -- build up the codes in the snd of each Leaf's tuple:
> mapBit b = map (second (b:)) . build
</code></pre><h3 id="endecoding-functions">(En/De)coding Functions</h3>
<pre tabindex="0"><code class="language-lhs" data-lang="lhs">To encode a list of symbols for which we've generated an HTree, we just
map over it, looking up it's code in our Map dictionary:
> encode :: (Ord a) => CodeDict a -> [a] -> [Bit]
> encode d = concatMap (d M.!)
To decode we simply read a Bit at a time from the input, at the same time
traversing the HTree (going left when we encounter a zero, and vice versa).
When we hit a Leaf (the end of a code) we return the symbol and go onto
the next bit from the top of the HTree once again.
> decode :: HTree a -> [Bit] -> [a]
> decode t [] = []
> decode t bs = dec bs t
> where dec bs' (Leaf x _) = x : decode t bs'
> dec (O:bs') (Branch l _ _) = dec bs' l
> dec (I:bs') (Branch _ r _) = dec bs' r
</code></pre><h3 id="usage-examples">Usage Examples</h3>
<p><strong>UPDATE</strong>: I scrapped and re-did this section. Should be a little better now.:</p>
-
Run-length Encoding
https://brandon.si/code/run-length-encoding/
Tue, 26 May 2009 00:00:00 +0000
https://brandon.si/code/run-length-encoding/
<p>Just a quick implementation of a
<a href="https://en.wikipedia.org/wiki/Run-length_encoding"> RLE algorithm</a> for lists in haskell. We compress a list by converting
“runs” of consecutive elements into a tuple of the form: (run length,
element).</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-haskell" data-lang="haskell"><span style="display:flex;"><span><span style="color:#66d9ef">import</span> Data.List (<span style="color:#a6e22e">group</span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">import</span> Control.Arrow
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">runLengthEnc</span> <span style="color:#f92672">::</span> <span style="color:#66d9ef">Eq</span> a <span style="color:#f92672">=></span> [a] <span style="color:#f92672">-></span> [(<span style="color:#66d9ef">Int</span>,a)]
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">runLengthEnc</span> <span style="color:#f92672">=</span> map (length <span style="color:#f92672">&&&</span> head) <span style="color:#f92672">.</span> group
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">decode</span> <span style="color:#f92672">::</span> [(<span style="color:#66d9ef">Int</span>, a)] <span style="color:#f92672">-></span> [a]
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">decode</span> <span style="color:#f92672">=</span> concatMap (uncurry replicate)
</span></span></code></pre></div><p>If the <code>&&&</code> combinator looks foreign to you, check out David R. Maciver’s
<a href="https://www.drmaciver.com/2007/08/playing-with-arrows/">very enlightening blog about Arrow functions</a>.</p>
-
Partial Application and a simple Mastermind game
https://brandon.si/code/partial-application-and-a-simple-mastermind-game/
Sun, 17 May 2009 00:00:00 +0000
https://brandon.si/code/partial-application-and-a-simple-mastermind-game/
<p>I thought this was a good, simple example of how
<a href="https://www.haskell.org/haskellwiki/Currying">currying and partial application</a> can be used in a
very expressive way. We create a one-liner to play the game
<a href="https://en.wikipedia.org/wiki/Mastermind_%28board_game%29">mastermind</a>.</p>
<p>In the type signature we include unnecessary parentheses, to be clear that we
are thinking of the function not as <em>“a function taking a secret code and a
guess and returning a score for the guess”</em> but as <em>“a function taking a
secret code and returning a scoring function for that code”</em>.</p>
-
Gnome Sort
https://brandon.si/code/gnome-sort/
Mon, 11 May 2009 00:00:00 +0000
https://brandon.si/code/gnome-sort/
<p>In my boredom, I implemented the toy sorting algorithm called
<a href="https://www.cs.vu.nl/~dick/gnomesort.html">Gnome Sort</a>. It accomplishes backtracking
by using a zipper-like system of two lists treated as stacks, and is about
100X slower than GHC’s merge sort on
<a href="https://neilmitchell.blogspot.com/2008/03/sorting-at-speed.html">the test I used</a>. It’s
also not especially small or simple-looking. It’s basically terrible:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-haskell" data-lang="haskell"><span style="display:flex;"><span><span style="color:#a6e22e">gnomeSort</span> <span style="color:#f92672">::</span> (<span style="color:#66d9ef">Ord</span> a)<span style="color:#f92672">=></span> [a] <span style="color:#f92672">-></span> [a]
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">gnomeSort</span> <span style="color:#f92672">=</span> sort <span style="color:#66d9ef">[]</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">where</span> sort rs <span style="color:#66d9ef">[]</span> <span style="color:#f92672">=</span> rs
</span></span><span style="display:flex;"><span> sort <span style="color:#66d9ef">[]</span> (x<span style="color:#66d9ef">:</span>xs) <span style="color:#f92672">=</span> sort [x] xs
</span></span><span style="display:flex;"><span> sort (r<span style="color:#66d9ef">:</span>rs) (x<span style="color:#66d9ef">:</span>xs)
</span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> x <span style="color:#f92672">></span> r <span style="color:#f92672">=</span> sort rs (x<span style="color:#66d9ef">:</span>r<span style="color:#66d9ef">:</span>xs)
</span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> otherwise <span style="color:#f92672">=</span> sort (x<span style="color:#66d9ef">:</span>r<span style="color:#66d9ef">:</span>rs) xs
</span></span></code></pre></div><p>The above doesn’t keep track of where it left off before it began to
backtrack, an obvious optimization which turned the algorithm into an
insertion sort:</p>
-
directory-tree module released
https://brandon.si/code/directory-tree-module-released/
Sat, 09 May 2009 00:00:00 +0000
https://brandon.si/code/directory-tree-module-released/
<p>I’ve released my first package,
<a href="https://hackage.haskell.org/cgi-bin/hackage-scripts/package/directory-tree">up now on hackage</a>
(haddock docs should be
generated soon). The module provides a simple data structure that mirrors a
directory tree, and some useful functions for doing IO on directories of
files. You can
<a href="https://brandon.si/code/a-directorytree-module-and-some-examples/">read more about it here</a>.</p>
<p>It’s very likely there are some bugs, especially related to cross platform
issues with file names and paths. The module is also fairly bare, so please
send me any requests for functionality that I haven’t thought of, as well as
any bugs you might find.</p>
-
a DirectoryTree module and some examples
https://brandon.si/code/a-directorytree-module-and-some-examples/
Thu, 30 Apr 2009 00:00:00 +0000
https://brandon.si/code/a-directorytree-module-and-some-examples/
<blockquote>
<p><strong>UPDATE</strong>: I’ve just released this as my first package on hackage. You can read
more and write any comments <a href="https://brandon.si/code/directory-tree-module-released/">here</a>.</p>
</blockquote>
<p>I just put together a library that provides a simple tree data structure to
represent the structure of files and directories in the OS. It provides some
simple IO functions like <code>readDirectory</code> (analogous to <code>readFile</code>) which
“opens” a directory, returning a DirTree of Strings in the IO monad.</p>
<p>The nice thing is that by defining a simple instance for
<a href="https://haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html">Traversable</a>
(and the default instances for Foldable and Functor that we
get for free) we get a whole array of nice functions which we can apply to
directory structures! For example, we can combine all the text in a directory
of files with:</p>
-
Why I love Hoogle
https://brandon.si/code/why-i-love-hoogle/
Sat, 25 Apr 2009 00:00:00 +0000
https://brandon.si/code/why-i-love-hoogle/
<p>I’m working on a module called <code>DirectoryTree</code>, a simple tree structure
mirroring the structure of a directory tree in the
<a href="https://en.wikipedia.org/wiki/Input/output">outside world</a>, with functions to hopefully
make it easy to do useful things (I’m not sure if something like this already
exists). Here is the data-type:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-haskell" data-lang="haskell"><span style="display:flex;"><span><span style="color:#66d9ef">data</span> <span style="color:#66d9ef">DirTree</span> a <span style="color:#f92672">=</span> <span style="color:#66d9ef">Dir</span> { name <span style="color:#f92672">::</span> <span style="color:#66d9ef">String</span>,
</span></span><span style="display:flex;"><span> files <span style="color:#f92672">::</span> [a],
</span></span><span style="display:flex;"><span> directories <span style="color:#f92672">::</span> [<span style="color:#66d9ef">DirTree</span> a] }
</span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> <span style="color:#66d9ef">Fail</span> <span style="color:#66d9ef">String</span> <span style="color:#75715e">--file/directory name</span>
</span></span></code></pre></div><p>I would like to do things like map over a <code>DirTree</code> of <code>FilePath</code>s, returning
a tree (in the IO monad) of <code>Handle</code>s… so the code involves a lot of
slogging through the IO monad, which I’m not totally comfortable with yet.</p>
-
Initial tests of Tries: Follow Up
https://brandon.si/code/initial-tests-of-tries-follow-up/
Sat, 18 Apr 2009 00:00:00 +0000
https://brandon.si/code/initial-tests-of-tries-follow-up/
<p>This is to wrap up my
<a href="https://brandon.si/code/some-initial-tests-of-tries/">previous post about Tries</a>
and my attempts at an implementation, and to summarize some of the things I
think I learned about implementing a Trie structure in Haskell.</p>
<h3 id="complexity-is-slow">Complexity is Slow</h3>
<p>My initial idea of using a container type at each node to store the collection
of branches was a good idea for testing (I could easily swap in Data.Map, or
my own simple binary tree) and convenience (I could use Data.Map’s built-in
functions to insert the element of the list key into the the container); but
it turned out to be bad for performance.</p>
-
Some initial tests of Tries
https://brandon.si/code/some-initial-tests-of-tries/
Thu, 16 Apr 2009 00:00:00 +0000
https://brandon.si/code/some-initial-tests-of-tries/
<p>I have been interested in writing a <a href="https://en.wikipedia.org/wiki/Trie">Trie</a>
implementation to see how its performance compares to using Data.Map for
storing dictionary-like data. I wrote a minimal implementation of Tries which
exports <code>insert</code>,<code>insertWith</code>, and <code>lookup</code> definitions and can be used in
place of <code>Data.Map</code> for those functions. I tested the implementation using a
program <code>frequency.hs</code> which reads a source file and uses <code>insertWith</code> on each
word to count the frequency of the words in a file; we then use <code>lookup</code> to
print out the frequencies of a list of arbitrary words.</p>
-
Cycle Detection
https://brandon.si/code/cycle-detection/
Sun, 12 Apr 2009 00:00:00 +0000
https://brandon.si/code/cycle-detection/
<h3 id="the-algorithm">The Algorithm</h3>
<p>We can use <a href="https://en.wikipedia.org/wiki/Cycle_detection#Brent.27s_algorithm">Brent’s Algorithm</a>
to detect infinitely-repeating sequences in a list of values generated by some
iterated function: that is, any list in which the next value in the sequence
is generated from the previous value alone; if we find duplicate values in the
list, we know we have a cycle.</p>
<p>The implementation below isn’t particularly elegant, and since I want to use
it as a stand-alone tool I’m having it output strings:</p>
-
Parallel List Comprehensions with a Monte Carlo example
https://brandon.si/code/parallel-list-comprehensions-with-a-monte-carlo-example/
Wed, 08 Apr 2009 00:00:00 +0000
https://brandon.si/code/parallel-list-comprehensions-with-a-monte-carlo-example/
<p>GHC has an extension to the list comprehensions syntax that replicates the
functionality of <code>zipWith</code>, by allowing you to have two generators running in
parallel. Turn on the extension in GHCi like so:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>Prelude> :set -XParallelListComp
</span></span></code></pre></div><p>I use the extension below to generate an infinite list of random coordinates
(scaled to a 1000x1000 grid) using two different
<a href="https://en.wikipedia.org/wiki/Linear_congruential_generator">Linear Congruential Generators</a>
running in parallel. It should be simple to modify the code below to actually run the
generators concurrently using
<a href="https://www.haskell.org/haskellwiki/GHC/Data_Parallel_Haskell">Data Parallel Haskell</a>
(although I haven’t had a chance to play with that yet).</p>
-
The Total Recall combinator
https://brandon.si/code/the-total-recall-combinator/
Wed, 01 Apr 2009 00:00:00 +0000
https://brandon.si/code/the-total-recall-combinator/
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-haskell" data-lang="haskell"><span style="display:flex;"><span><span style="color:#66d9ef">infixr</span> <span style="color:#ae81ff">9</span> <span style="color:#f92672">.:</span>
</span></span><span style="display:flex;"><span>(<span style="color:#f92672">.:</span>) <span style="color:#f92672">::</span> (b <span style="color:#f92672">-></span> c) <span style="color:#f92672">-></span> (a <span style="color:#f92672">-></span> a1 <span style="color:#f92672">-></span> b) <span style="color:#f92672">-></span> a <span style="color:#f92672">-></span> a1 <span style="color:#f92672">-></span> c
</span></span><span style="display:flex;"><span>(<span style="color:#f92672">.:</span>) <span style="color:#f92672">=</span> (<span style="color:#f92672">.</span>)(<span style="color:#f92672">.</span>)(<span style="color:#f92672">.</span>)
</span></span></code></pre></div><p>This can be used to compose a string of functions with a binary function stuck
on the end. For example:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-haskell" data-lang="haskell"><span style="display:flex;"><span><span style="color:#a6e22e">lookupPlusOne</span> <span style="color:#f92672">::</span> (<span style="color:#66d9ef">Ord</span> k, <span style="color:#66d9ef">Monad</span> m, <span style="color:#66d9ef">Num</span> n) <span style="color:#f92672">=></span> k <span style="color:#f92672">-></span> <span style="color:#66d9ef">Map</span> k n <span style="color:#f92672">-></span> m n
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">lookupPlusOne</span> <span style="color:#f92672">=</span> liftM (<span style="color:#f92672">+</span><span style="color:#ae81ff">1</span>) <span style="color:#f92672">.:</span> lookup
</span></span></code></pre></div><p>(picked up from some folks on
<a href="https://www.haskell.org/haskellwiki/IRC_channel">#haskell</a>)</p>
-
Building a Tree from an Ordered List
https://brandon.si/code/building-a-tree-from-an-ordered-list/
Tue, 31 Mar 2009 00:00:00 +0000
https://brandon.si/code/building-a-tree-from-an-ordered-list/
<p>A nice recursive algorithm for building a nearly-optimal binary search
tree from an <strong>ordered list</strong>.:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-haskell" data-lang="haskell"><span style="display:flex;"><span><span style="color:#66d9ef">data</span> <span style="color:#66d9ef">Tree</span> a <span style="color:#f92672">=</span> <span style="color:#66d9ef">Node</span> a (<span style="color:#66d9ef">Tree</span> a) (<span style="color:#66d9ef">Tree</span> a)
</span></span><span style="display:flex;"><span> <span style="color:#f92672">|</span> <span style="color:#66d9ef">End</span>
</span></span></code></pre></div><p>The algorithm <code>divide</code>s the input list into sublists of increasing length:
1,2,4,8… The first element of each sublist is the “keystone” of a subtree
assembled with <code>mkTree</code>. :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-haskell" data-lang="haskell"><span style="display:flex;"><span><span style="color:#a6e22e">fromSorted</span> <span style="color:#f92672">::</span> [a] <span style="color:#f92672">-></span> <span style="color:#66d9ef">Tree</span> a
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">fromSorted</span> <span style="color:#f92672">=</span> foldl mkTree <span style="color:#66d9ef">End</span> <span style="color:#f92672">.</span> divide <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">where</span> mkTree l (n<span style="color:#66d9ef">:</span>ns) <span style="color:#f92672">=</span> <span style="color:#66d9ef">Node</span> n l (fromSorted ns)
</span></span><span style="display:flex;"><span> divide <span style="color:#66d9ef">_</span> <span style="color:#66d9ef">[]</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">[]</span>
</span></span><span style="display:flex;"><span> divide c xs <span style="color:#f92672">=</span> take c xs <span style="color:#66d9ef">:</span> divide (c<span style="color:#f92672">*</span><span style="color:#ae81ff">2</span>) (drop c xs)
</span></span></code></pre></div><p>Variations that used <code>splitAt</code> instead of the separate <code>take</code> and <code>drop</code> were
no more efficient (perhaps because of
<a href="https://www.haskell.org/haskellwiki/Sharing">sharing</a>?) nor was using the
strict <code>foldl'</code>.</p>
-
Data.Map Conversion Functionality
https://brandon.si/code/datamap-functions/
Sun, 29 Mar 2009 00:00:00 +0000
https://brandon.si/code/datamap-functions/
<p>There are three identical functions in <code>Data.Map</code> for flattening a Map to a
list of tuples in ascending order:</p>
<blockquote>
<p><code>assocs = toList = toAscList</code></p>
</blockquote>
<p>…but nothing to convert to a descending list.</p>