tag:dreamwidth.org,2010-05-25:518115My superpower is synchronicitywren gayle romanowren gayle romano2014-03-11T01:49:03Ztag:dreamwidth.org,2010-05-25:518115:91968A crash course in topos theory2014-03-11T01:49:03Z2014-03-11T01:49:03Zpublic2<p>I ended up spending this weekend learning a lot about topos theory. Why? I have no idea. But for whatever reason, this happened. Like many areas of category theory, the biggest hurdle is figuring out the terminology— in particular, figuring out what terminology you actually need to know now vs the terminology you can put off learning until later.</p>
<p>So, with that in mind, I threw together <a href="http://cl.indiana.edu/~wren/resources/cartography-of-math/TopoiLogoi.pdf">a quick sketch of topos/logos theory</a>. I should emphasize that this is only a <i>very quick</i> sketch. It shows when one kind of category is also another kind of category, but for the most part[1] it doesn't say what the additional characteristics of the subkind are (unlike in my other terminology maps). One major thing missing from this sketch is a notation for when one kind of category is exactly the intersection of two other kinds (e.g., a pretopos is <i>precisely</i> an extensive exact category). Once I figure out how to show that in PSTricks, I'll post a new version. As before, the dashed lines indicate things you get for free (e.g., every pretopos is coherent for free). The dotted line from Heyting categories to well-powered geometric categories is meant to indicate that, technically, all WPG categories are also Heyting categories, but the Heyting structure is not preserved by geometric functors and therefore should not be "relied on" when reasoning about WPG categories as a whole. And finally, the table at the bottom shows what operators exist in the internal logic of these various categories, as well as what structure the subobject posets have.</p>
<p>Despite being far less polished than my other maps, hopefully it'll give you enough to go on so that you can read through the pages at <a href="http://ncatlab.org/">n-lab</a> in the correct order.</p>
<p>[1] For the arcs which are explained, the following abbreviations are used: "So.C." = subobject classifier; "AMC" = axiom of multiple choice; "NNO" = natural numbers object.; "LCCC" = locally cartesian closed.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=91968" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:91887I am so done with this past week.2014-02-27T22:09:05Z2014-02-27T22:09:05Zpublic2<p>Saturday night I had a fainting spell.
Sunday my eyes were burning, I was feverish, weak, and had the beginnings of a migraine.
Monday was completely lost in the blaze of a migraine.
Tuesday I was starting to feel better— and then, nope; threw up that night.
Wednesday I awoke with what felt like a raging sinus infection; spent the whole day in a haze of sudafed and ibuprofen, and went through literally an entire box of tissues.</p>
<p>Starting to feel a little better this morning, so I figure this is the end. It was a nice life. Y'might want to bar your doors today, just in case it's locusts.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=91887" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:91282What is the type of the derivative operator?2014-02-13T04:15:25Z2014-02-18T07:10:59Zpublic5<p>I've been mucking about with real analysis lately. One of the things I've always hated about real analysis (and complex analysis, and other calculus) is the unrepentant lack of types. It's easy to get confused about what's going on and what goes where when you think everything is a real number (or complex number, or tensors thereof). In particular, because of this "everything is a real array" assumption, libraries for performing optimization etc end up with utterly inscrutable APIs and other nastiness like needing to manually flatten your parameters into a single array. So this has got me thinking, what <i>should</i> the API for optimization libraries look like? Which in turn brings me back to an age-old conundrum I've toyed around with before, namely: what is the type of the derivative operator?</p>
<p>From the "everything is a real number" perspective we'd say <code>deriv : (ℝ ↝ ℝ) → ℝ → ℝ</code>, where the <code>A ↝ B</code> function space are "nice" functions (e.g., continuous, smooth, analytic, whatever). However, this only works out because we're conflating a number of important differences. For example, for any affine space <code>A</code> we have the difference space <code>∆A</code>— that is, values in <code>∆A</code> denote differences or differentials of values in <code>A</code> (e.g., for any <code>a : A</code> and <code>b : A</code> we have <code>a-b : ∆A</code>). However, it turns out that there's a bijection between <code>ℝ</code> and <code>∆ℝ</code>. It also turns out that the difference of arrays, <code>∆(ℝ<sup>n</sup>)</code>, is isomorphic to an array of differences, <code>(∆ℝ)<sup>n</sup></code>. Putting these together we get the common conflation between points (<code>ℝ<sup>n</sup></code>) and vectors (<code>∆(ℝ<sup>n</sup>)</code>). For another example, consider linear transformations, written <code>A ⊸ B</code>. We have a bijection between linear transformations (<code>ℝ<sup>m</sup> ⊸ ℝ<sup>n</sup></code>) and matrices (<code>ℝ<sup>n×m</sup></code>), and hence more specifically a bijection between <code>ℝ</code> and <code>ℝ ⊸ ℝ</code>.</p>
<p>So here's what I'm currently thinking:</p>
<blockquote><p><code>deriv : (F X ↝ Y) → F X → F(∆X ⊸ ∆Y)</code></p></blockquote>
<p>For now, just ignore <code>F</code>; instantiate it as the identity functor. Thus, the total derivative of <code>f : X ↝ Y</code> at the point <code>x : X</code> is a linear transformation from minor perturbations about <code>x</code> to minor perturbations about <code>f x</code>. We can think of <code>∆X ⊸ ∆Y</code> as being the "slope" of this mapping between minor perturbations. In particular, when <code>X=ℝ</code> and <code>Y=ℝ</code>, we get a bijection between <code>∆ℝ ⊸ ∆ℝ</code> and <code>ℝ</code>, so this coincides with the traditional notion of the slope of a one-dimensional curve.</p>
<p>Now, let's think about the gradient rather than the total derivative. Assume that <code>F</code> is a "nice" functor (i.e., representable, traversable, etc). Because the functor is representable, we have an isomorphism between <code>F A</code> and <code>I → A</code> (natural in <code>A</code>), where <code>I</code> is the type of positions/indices in <code>F</code>. Thus, the gradient of a function <code>g : F X ↝ Y</code> at the point <code>z : F X</code> is essentially a function from <code>F</code>-indices, <code>i : I</code>, to the <code>i</code>-th partial derivative of <code>g</code> at <code>z</code>. Why partial derivative? Because the linear transformation only takes <code>∆X</code> as an argument —not <code>∆(F X)</code>—, thus we can only modify a single "scalar" at a time, and the other scalars in <code>z</code> must remain fixed.</p>
<p><i>Edit 2014.02.17 (#1):</i> Actually, things are a bit more complicated than the above. For example, consider a function <code>f : ℝ<sup>n</sup> ↝ ℝ</code>. The derivative of <code>f</code> with respect to its <i>vector</i> of inputs is not a vector of partial derivatives— rather, it's a <i>covector</i> of partial derivatives! (i.e., <code>deriv (f : ℝ<sup>n×1</sup> ↝ ℝ) : ℝ<sup>n×1</sup> → ℝ<sup>1×n</sup></code>.) Thus, we should really have that the return type of <code>deriv</code> is some <code>F<sup>op</sup>(∆X ⊸ ∆Y)</code> where <code>F<sup>op</sup></code> is some sort of "dual" of <code>F</code>. It's not clear a priori which notion of "duality" is in play here, however.</p>
<p><i>Edit 2014.02.17 (#2):</i> And here's what I'm currently thinking about how to incorporate the Jacobian into the above. Consider this particular instance of the derivative operator, <code>deriv : (F X ↝ G Y) → F X → F<sup>op</sup>(∆X ⊸ ∆(G Y))</code>. When <code>G</code> is some type of vectors (e.g., <code>G Y = Y<sup>n</sup></code> for some fixed <code>n</code>), we get <code>∆(G Y) = G(∆Y)</code> as mentioned before. And let's assume <code>∆X ⊸ G(∆Y) = G(∆X ⊸ ∆Y)</code>; presumably this follows immediately by linearity, though I haven't verified that yet. And finally, in our standard real analysis we get that <code>G∘F<sup>op</sup></code> and <code>F<sup>op</sup>∘G</code> are the same— that is, vectors-of-covectors and covectors-of-vectors are essentially the same thing; they're just the row-major and column-major representations of matrices, respectively. And then, putting all these together we get that the original return type <code>F<sup>op</sup>(∆X ⊸ ∆(G Y))</code> is isomorphic to <code>G(F<sup>op</sup>(∆X ⊸ ∆Y))</code>. So when <code>X=ℝ</code> and <code>Y=ℝ</code> we get the expected <code>deriv : (ℝ<sup>m</sup> ↝ ℝ<sup>n</sup>) → ℝ<sup>m</sup> → ℝ<sup>n×m</sup></code>. Now, it remains to show how this extends to other choices of <code>F</code> and <code>G</code>...</p>
<p><i>Edit 2014.02.17 (#3):</i> It was pointed out <a href="http://www.reddit.com/r/haskell/comments/1xwbb8/what_is_the_type_of_the_derivative_operator/cffjkz8">on reddit</a> that the above is "well known"— at least for those who are familiar with <a href="http://en.wikipedia.org/wiki/Differentiable_manifold#Differential_calculus_of_functions">differentiable manifolds and tangent spaces</a>. Now, I don't know much about manifolds, but it certainly wasn't well-known to me— which, in itself, says a lot about how little this knowledge has spread to the rest of mathematics. I'm glad to hear there's some followup reading to be done here, but I still don't think the necessary work has been done in terms of turning this into a decent API for optimization libraries.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=91282" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:90905Seminearrings2014-02-06T02:11:51Z2014-02-07T00:00:26Zpublic2<p>So there was a discussion recently on the libraries mailing list about how to deal with <code>MonadPlus</code>. In particular, the following purported law fails all over the place: <code>x >> mzero = mzero</code>. The reason it fails is that we are essentially assuming that any "effects" that <code>x</code> has can be undone once we realize the whole computation is supposed to "fail". Indeed this rule is too strong to make sense for our general notion that <code>MonadPlus</code> provides a notion of choice or addition. I propose that the correct notion that <code>MonadPlus</code> should capture is that of a <b><i>right-seminearring</i></b>. (The name right-nearsemiring is also used in the literature.) Below I explain what the heck a (right-)seminearring is.</p>
<h3>Monoids</h3>
<p>First, I will assume you know what a monoid is. In particular, it's any <i>associative</i> binary operation with a distinguished element which serves as both <i>left- and right-identity</i> for the binary operation. These are ubiquitous and have become fairly well-known in the Haskell community of late. A prime example is <code>(+,0)</code> —that is, addition together with the zero element; for just about any any notion of "numbers". Another prime example is <code>(*,1)</code>— multiplication together with unit; again, for just about any notion of "numbers".</p>
<p>An important caveat regarding intuitions is that: both "addition" and "multiplication" of our usual notions of numbers turn out to be <i>commutative</i> monoids. For the non-commutative case, let's turn to regular expressions (regexes). First we have the notion of regex catenation, which captures the notion of sequencing: first we match one regex and then another; let's write this as <code>(*,1)</code> where here we take <code>1</code> to mean the regex which matches only the empty string. This catenation of strings is very different from multiplication of numbers because we can't swap things around. The regex <code>a*b</code> will first match <code>a</code> and <i>then</i> match <code>b</code>; whereas the regex <code>b*a</code> will match <code>b</code> first. Nevertheless, catenation (of strings/sequences/regexes/graphs/...) together with the empty element still forms a monoid because catenation is associative and catenating the empty element does nothing, no matter which side you catenate on.</p>
<p>Importantly, the non-deterministic choice for regexes also forms a monoid: <code>(+,0)</code> where we take <code>0</code> to be the absurd element. Notably, the <i>empty</i> element (e.g., the singleton set of strings, containing only the empty string) is distinct from the <i>absurd</i> element (e.g., the empty set of strings). We often spell <code>1</code> as <code>ε</code> and spell <code>0</code> as <code>∅</code>; but I'm going to stick with the arithmetical notation of <code>1</code> and <code>0</code>.</p>
<h3>Seminearrings</h3>
<p>Okay, so what the heck is a right-seminearring? <b>First,</b> we assume some ambient set of elements. They could be "numbers" or "strings" or "graphs" or whatever; but we'll just call them elements. <b>Second,</b> we assume we have a semigroup <code>(*)</code>— that is, our <code>*</code> operator is associative, and that's it. Semigroups are just monoids without the identity element. In our particular case, we're going to assume that <code>*</code> is <i>non-commutative</i>. Thus, it's going to work like catenation— except we don't necessarily have an empty element to work with. <b>Third,</b> we assume we have some monoid <code>(+,0)</code>. Our <code>+</code> operator is going to act like non-deterministic choice in regexes— but, we're not going to assume that it's commutative! That is, while it represents "choice", it's some sort of <i>biased choice</i>. Maybe we always try the left option first; or maybe we always try the right option first; or maybe we flip a biased coin and try the left option first only 80% of the time; whatever, the point is it's not entirely non-deterministic, so we can't simply flip our additions around. <b>Finally,</b> we require that our <code>(*)</code> semigroup distributes <i>from the right</i> over our <code>(+,0)</code> monoid (or conversely, that we can factor the monoid out from under the semigroup, again only factoring out parts that are on the <i>right</i>). That is, symbolically, we require the following two laws to hold:
<blockquote><p><code>0*x = 0</code><br />
<code>(x+y)*z = (x*z)+(y*z)</code></p></blockquote>
<p>So, what have we done here? Well, we have these two interlocking operations where "catenation" distributes over "choice". What the first law mean is that: (1) if we first do something absurd or impossible and then do <code>x</code>, well that's impossible. We'll never get around to doing <code>x</code> so we might as well just drop that part. The second law means: (2) if we first have a choice between <code>x</code> and <code>y</code> and then we'll catenate whichever one with <code>z</code>, this is the same as saying our choice is really between doing <code>x</code> followed by <code>z</code> vs doing <code>y</code> followed by <code>z</code>.</p>
<h3>MonadPlus</h3>
<p>Okay, so what does any of this have to do with <code>MonadPlus</code>? Intuitively, our <code>*</code> operator is performing catenation or sequencing of things. Monads are all about sequencing. So how about we use the monad operator <code>(>>)</code> as our "multiplication"! This does what we need it to since <code>(>>)</code> is associative, by the monad laws. In order to turn a monad into a <code>MonadPlus</code> we must define <code>mplus</code> (aka the <code>+</code> operator) and we must define a <code>mzero</code> (aka the <code>0</code> element). And the laws our <code>MonadPlus</code> instance must uphold are just the two laws about distributing/factoring on the right. In restating them below, I'm going to generalize the laws to use <code>(>>=)</code> in lieu of <code>(>>)</code>:</p>
<blockquote><p><code>mzero >>= f = mzero</code><br />
<code>(x `mplus` y) >>= f = (x >>= f) `mplus` (y >>= f)</code></p></blockquote>
<p>And the reason why these laws make sense are just as described before. If we're going to "fail" or do something absurd followed by doing something else, well we'll never get around to that something else because we've already "failed". And if we first make a choice and then end up doing the same thing regardless of the choice we made, well we can just push that continuation down underneath the choice.</p>
<p>Both of these laws make intuitive sense for what we want out of <code>MonadPlus</code>. And given that seminearrings are something which have shown up often enough to be named, it seems reasonable to assume that's the actual pattern we're trying to capture. The one sticking point I could see is my generalization to using <code>(>>=)</code>. In the second law, we allow <code>f</code> to be a function which "looks inside" the monad, rather than simply being some fixed monadic value <code>z</code>. There's a chance that some current <code>MonadPlus</code> implementations will break this law because of that insight. If so, then we can still back off to the weaker claim that <code>MonadPlus</code> should implement a right-seminearring <i>exactly</i>, i.e., with the <code>(>>)</code> operator as our notion of multiplication/catenation. <span style="text-decoration:line-through;">This I leave as an exercise for the reader.</span> This is discussed further in the addendum below.</p>
<p>Notably, from these laws it is impossible to derive <code>x*0 = 0</code>, aka <code>x >> mzero = mzero</code>. And indeed that is a stringent requirement to have, since it means we must be able to undo the "effects" of <code>x</code>, or else avoid doing those "effects" in the first place by looking into the future to know that we will eventually "fail". If we could look into the future to know we will fail, then we could implement backtracking search for logic programming in such a way that we <i>always pick the right answer.</i> Not just return results consistent with always choosing the right answer, which backtracking allows us to do; but rather, to always know the right answer beforehand and so never need to backtrack! If we satisfy the <code>x*0 = 0</code> law, then we could perform all the "search" during compile time when we're applying the rewrite rule associated with this law.</p>
<h3>Addendum</h3>
<p>There's a <a href="http://www.haskell.org/haskellwiki/MonadPlus">long history of debate</a> between proponents of the generalized distribution law I presented above, vs the so-called "catch" law. In particular, <code>Maybe</code>, <code>IO</code>, and <code>STM</code> obey the catch law but do not obey the generalized distribution law. To give an example, consider the following function:</p>
<blockquote><p><code>f a' = if a == a' then mzero else return a'</code></p></blockquote>
<p>Which is used in the following code and evaluation trace for the <code>Maybe</code> monad:</p>
<blockquote><p><code>mplus (return a) b >>= f</code><br />
<code>⟶ Just a >>= f</code><br />
<code>⟶ f a</code><br />
<code>⟶ if a == a then mzero else return a</code><br />
<code>⟶ mzero</code></p></blockquote>
<p>As opposed to the following code and evaluation trace:</p>
<blockquote><p><code>mplus (return a >>= f) (b >>= f)</code><br />
<code>⟶ mplus (f a) (b >>= f)</code><br />
<code>⟶ mplus mzero (b >>= f)</code><br />
<code>⟶ b >>= f</code></p></blockquote>
<p>But <code>b >>= f</code> is not guaranteed to be identical to <code>mzero</code>. The problem here is, as I suspected, because the generalized distribution law allows the continuation to "look inside". If we revert back to the non-generalized distribution law which uses <code>(>>)</code>, then this problem goes away— at least for the <code>Maybe</code> monad.</p>
<h3>Second Addendum (2014.02.06)</h3>
<p>Even though <code>Maybe</code> satisfies the non-generalized distributivity laws, it's notable that other problematic <code>MonadPlus</code> instances like <code>IO</code> fail even there! For example,</p>
<p>First consider <code>mplus a b >> (c >> mzero)</code>. Whenever <code>a</code> succeeds, we get that this is the same as <code>a >> c >> mzero</code>; and if <code>a</code> fails, then this is the same as <code>a' >> b >> c >> mzero</code> where <code>a'</code> is the prefix of <code>a</code> up until failure occurs.</p>
<p>Now instead consider <code>mplus (a >> c >> mzero) (b >> c >> mzero)</code>. Here, if <code>a</code> succeeds, then this is the same as <code>a >> c >> b >> c >> mzero</code>; and if <code>a</code> fails, then it's the same as <code>a' >> b >> c >> mzero</code>. So the problem is, depending on whether we distribute or not, the effects of <code>c</code> will occur once or twice.</p>
<p>Notably, the problem we're running into here is exactly the same one we started out with, the failure of <code>x >> mzero = mzero</code>. Were this law to hold for <code>IO</code> (etc) then we wouldn't run into the problem of running <code>c</code> once or twice depending on distributivity.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=90905" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:90663This Week in Review2014-02-02T05:59:11Z2014-02-02T06:08:12ZA/B Machines ~ Sleigh Bells (Treats)public4<p>Last friday I passed my qualifying examinations! So now, all I have left is a bunch of paperwork about that and then proposing, writing, and defending the dissertation itself. So, in about a year or so I'll be on the job market. And, much as I despise job hunting, I can't wait!</p>
<p>Since defending the quals I've been spending far too much time playing <i>Persona 3 Portable</i>. I've played <i>P3FES</i>, but <i>P3P</i> adds a female protagonist option which changes a bunch of the social interactions, so I've been playing through that side of things. Other than the heterosexual assumptions about the relationships, I've been loving it. More rpgs should have female protagonists. That's one of the reasons I've always loved <i>FF6</i>. Also a big part of why I found <i>FF13</i> compelling. (Though, tbh: while Lightning is awesome as a protagonist, Vanille is definitely my favorite character :) And a big part of <a href="http://quinnae.com/2013/07/07/for-she-has-tasted-the-fruit/">the powerfulness of Kreia as a character</a> in <i>KotOR2</i> stems from her interactions with the canonically-female protagonist.</p>
<p>Speaking of women. I've been presenting as female for a couple months now, and since I have no intention of stopping nor hiding that fact, I've decided to move T-Day forward. Basically, for those who haven't already switched over to the right pronouns etc: T-Day is today. I've sent emails to the department heads in order to get them to send out the "official" memo; so if you haven't gotten it yet, that should show up on monday or tuesday.</p>
<p>The next couple months are going to be hectic with paper writing. I'm hoping to get a paper on syntax-based sentiment-analysis using matrix-space semantics into one of the CL conferences with deadlines this March. No Haskell involved in that one, though I'll probably spend a few posts discussing the semantic model, which may be of interest to y'all. I'm also planning on getting the work from my first qual paper published; that paper was about <a href="http://winterkoninkje.dreamwidth.org/tag/pos+tagging">Posta</a>, a functional library for interactive/online/incremental tagging with HMMs. Here I'm planning to target journals rather than conferences, and it'll spread out over a few papers: one on the overall system (which I need to actually push up to Hackage), one on the higher-order anytime <code>n</code>-best extraction algorithm, and one on reformulating HMM algorithms in terms of <code>foldl</code> and <code>scanl</code> (this may be combined with the HO-AnB paper, length permitting). All of these would be targeting the linguistics audience. Using folds and scans is old-hat in functional programming; my particular goal with that paper is exposing linguists to the tools of FP and how they can be used to greatly simplify how we describe our algorithms. Once those are out of the way I might also see about writing up a functional pearl on the smoothing library I presented at <a href="http://cl.indiana.edu/~wren/pubs/smoothing_ammcs2011.pdf">AMMCS</a> a few years back.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=90663" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:90440In which a conundrum is discussed2014-01-20T23:22:00Z2014-01-20T23:22:00Zpublic1<p>Now that the hectic chaos of last semester is past, I've been thinking of getting back into blogging again. I started tweeting a few months back, and since then I've gotten back into activism and gathered a new batch of friends who talk about all manner of interesting things. Both of these —friendships and activism— have long been motivating forces for my thinking and writing. And so, excited by tweeting, I've been wanting to write again in a less ephemeral medium.</p>
<p>But I face something of a conundrum.</p>
<p>When I started blogging it was always just a place for me to ramble out thoughts on whatever passes through my head. It was never my goal to keep the blog focused on any particular topic. After leaving Portland, and lacking the wide network of friends I was used to there, I dove headlong into the Haskell community. In addition, a few years back, I started working on a major Haskell project (from which most of my published Haskell code derives). So, for a time, the vast majority of my blogging was dominated by Haskell, which is why I signed up to be syndicated on Haskell Planet.</p>
<p>To be clear, I have no intention of leaving the Haskell community for the foreseeable future. I still use Haskell regularly, still teach it to others, etc. However, of late, my thoughts have been elsewhere. Computationally I've been focusing more on type theory and category theory themselves, rather than their uses and applications in Haskell per se. Linguistically I've been looking more into semantic issues, as well as some of the newer models for incorporating syntax into NLP. Sociologically I've been, as I said, thinking a lot more about social justice issues. Not to mention more casual things like reading, gaming, cooking, and all that.</p>
<p>Back when I joined the Planet it was pretty active and had lots of material which was only loosely related to Haskell; e.g., all the musicians and live coders who used Haskell for their work. I loved this wide-ranging view of Haskell, and this diversity is a big part of why I fell in love with the community. In such an environment, I think my blog fits well enough. However, over the years I've noticed the Planet becoming far more narrow and focused on code development alone. I think Phil Wadler is probably the only one who goes on about other stuff these days. Given this trend, it's not so clear that my ramblings would mesh well with the Planet as it stands.</p>
<p>So that's where I'm at. Not sure whether to quit syndicating to Haskell Planet, or to make a special filtered feed for the Haskell-only stuff, or what. If you have any opinions on the matter, please do comment. Otherwise I'll prolly just start writing and wait for people to complain.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=90440" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:90159Email change2014-01-03T23:08:47Z2014-01-03T23:08:47Zpublic0<p>Heads up y'all. My email at Free Geek will be going away in about a month. The following addresses are all still valid and point to the right place:
<ul>
<li>cpan.org — for Perl folks</li>
<li>community.haskell.org — for Haskell folks</li>
<li>alumni.reed.edu — for Reedies</li>
<li>indiana.edu — for business</li>
<li>gmail.com — for friends</li>
</ul>
If you don't have one of those, email me (at freegeek.org) and I'll hook you up.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=90159" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:90012The Announcement2013-11-26T00:41:03Z2013-11-26T00:41:26Zpublic3<p>There are three parts to this post. Everyone should read the first two sections, especially the second section. Haskellers should also be sure to read the third section.</p>
<h3>The Announcement</h3>
<p>If you don't yet know: I'm transgender. My sense of gender and self have never aligned with my physical appearance, and I’ve spent most of my life dealing with this fact. This is not an acquired condition nor a recent change; it is an intrinsic and life-long part of who I am. I began the process of transitioning half a year ago and, over the next six months or so, I will complete the transition to living as a woman full-time.</p>
<p>Many of my followers are already familiar with transgender issues, but since this is a public announcement I assume many of you are not. There are numerous resources online for learning more, but I find <a href="http://community.pflag.org/Document.Doc?id=202">the PFLAG pamphlet</a> to be a particularly good place to start. If you still have any questions after reading that, I can provide additional resources and am willing to answer questions.</p>
<h3>How to respond</h3>
<p>This is going to depend on how you know me.</p>
<dl>
<dt>If we interact predominantly online</dt>
<dd>This includes everyone in the Haskell community (both online and academically), as well as everyone from Reddit, Twitter, etc. Henceforth, please use feminine pronouns (she/her/hers) exclusively when referring to me. I understand this will take some getting used to, but it will soon become second nature.</dd>
<dt>If we interact predominantly in person</dt>
<dd>I'd prefer you use feminine pronouns (she/her/hers) when referring to me, especially when online and when mentioning me anonymously. But, for the time being, masculine pronouns (he/him/his) are still acceptable. Sometime in the spring I will send another announcement around letting you know when "T-day" is. After that date, I will be presenting as female full-time and will no longer tolerate masculine pronouns.</dd>
</dl>
<hr />
<h3>PSA for Haskellers</h3>
<p>I shouldn't have to say this, but since there were some complaints about the "homosexual propaganda" in my recent posts, may I remind my readers of <a href="http://planet.haskell.org/faq.html">The Planet Haskell policies</a> regarding political and religious content. I rarely post political content, but am well within the guidelines in doing so. The stated mission of Planet Haskell is to "show what is happening in the community, what people are thinking about or doing". I am an active and well-known member of the Haskell community, and the violence endured by trans people is something I've been thinking a lot about lately. When Chung-chieh Shan gave <a href="http://conway.rutgers.edu/~ccshan/wiki/blog/posts/haskell2013/">the 2013 Haskell Symposium program chair report</a>, he made a specific point of highlighting the effects of sexism, racism, homophobia, and transphobia in driving people out of the Haskell community. Therefore, I think it is fair to say that these issues are pertinent, above and beyond my personal involvement with them.</p>
<p>That said, I do not intend to discuss trans issues at length on this blog. Nevertheless, on occasion, these issues will come up because I refuse to live in silence and shame for who I am.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=90012" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:89630It is done.2013-11-22T06:13:17Z2013-11-22T06:13:17Zpublic4<dl>
<dt>Things done today</dt>
<dd><ul>
<li>Gave my advisors The Letter. The public announcement is scheduled for monday</li>
<li>Handed in the revised version of qual #2. Clocked in at 59 pages. I'm not entirely satisfied with it, but sometimes y'just gotta let it go.</li>
</ul></dd>
<dt>What remains before I'm ABD</dt>
<dd><ul>
<li>P550 final paper. Target length 10 pages.</li>
<li>Qual #3, due by x-mas. This one is just a lit-review, and I've already read the lit, so it shouldn't take too long (I hope!)</li>
<li>Qual oral defense, the first week or two of Spring. Cakewalk expected</li>
<li>Dissertation proposal. Aiming to get it done by January</li>
</ul></dd></dl><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=89630" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:89461TDOR2013-11-20T07:44:51Z2013-11-20T17:19:46Zpublic0<p><b>On this day we <a href="http://www.transrespect-transphobia.org/uploads/downloads/2013/TDOR2013english/TvT-TMM-Namelist-TDOR2013_EN.pdf">remember our dead</a>.</b></p>
<p>When <a href="http://www.rawstory.com/rs/2013/10/29/trans-blogger-catches-california-christian-group-in-second-harassment-lie/">right-wing bigots lie</a> and <a href="http://www.transadvocate.com/spot-anti-trans-signature-gatherers-in-california-report-it-at-866-377-0578.htm">fabricate stories about trans* people</a>, you look at our dead and tell me with a straight face who should fear whom. While you worry about your kids <a href="http://freethoughtblogs.com/zinniajones/2013/11/transgender-women-in-womens-restrooms-a-purely-imagined-harm/">feeling nervous about nothing happening</a>, I'm too worried for the children who will one day soon be shot, strangled, suffocated, stabbed, tortured, beheaded, lit on fire, and thrown off bridges simply for existing.</p>
<p>And you on the left: I love all you queers, and I'm glad for your victories; but the next time you <a href="http://parkthatcar.net/2013/11/19/lgb-celebrate-while-the-t-mourns/">celebrate an "LGBT" victory</a> you take a long hard look at <a href="http://transgriot.blogspot.com/2007/10/why-transgender-community-hates-hrc.html">your history of throwing</a> <a href="http://caitlinsong.wordpress.com/2013/04/02/the-hrc-and-trans-exclusion/">that "T" under the bus</a> and you look at our dead and tell me with a straight face how it's not yet time to fight for trans* rights.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=89461" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:89010Website go bye bye2013-11-11T22:29:46Z2013-11-11T22:29:46Zpublic0<p>Heads up, the host I've been using for my website <a href="http://llama.freegeek.org/~wren/">llama.freegeek.org</a> will be going away on Sunday, 17 November 2013. Since I'm strapped for time, I won't be able to migrate it to another host for a while. Once I get a chance to set up a new one, I'll let y'all know.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=89010" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:88020TSA thinks: Terrorists aren't plotting to attack airplanes2013-10-22T04:48:24Z2013-10-22T04:48:24Zpublic0<p>Finally, hard evidence of what we've known all along: <a href="http://www.techdirt.com/articles/20131019/02322924936/accidentally-revealed-document-shows-tsa-doesnt-think-terrorists-are-plotting-to-attack-airplanes.shtml">Everything the TSA has been doing is a waste of time and money, and violates our privacy for no security gain whatsoever</a>.
<blockquote>quoted from the TSA's own statements: "As of mid-2011, terrorist threat groups present in the Homeland are not known to be actively plotting against civil aviation targets or airports; instead, their focus is on fundraising, recruiting, and propagandizing."</blockquote>
<blockquote>Elsewhere, in the redacted portions, the TSA is quoted as admitting that "there have been no attempted domestic hijackings of any kind in the 12 years since 9/11."</blockquote>
<blockquote>Amazingly, it appears that the government forced Corbett to redact the revelation that the TSA's own threat assessments have shown "literally zero evidence that anyone is plotting to blow up an airline leaving from a domestic airport."</blockquote><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=88020" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:87657Trigger Warning: Living while female.2013-10-20T02:18:10Z2013-10-20T02:18:10Zpublic0<p>Anyone who thinks sexism isn't such a big thing anymore, needs to read the following articles. Anyone who has been raised as male and thinks women's lives are essentially the same, needs to read the following articles. Anyone who wants to believe they aren't sexist or who wants to think of themselves as an "ally" to women, needs to read the following articles. Anyone who lives or works in academia, needs to read the following articles.</p>
<dl>
<dt><a href="http://www.shakesville.com/2013/10/the-terrible-bargain-we-have.html">The terrible bargain we have regretfully struck</a></dt>
<dd>quoth <a href="https://twitter.com/juliepagano">@juliepagano</a>: "If you are a man and have been confused about some of my anger and frustration recently, read the post."</dd>
<dt><a href="http://tenureshewrote.wordpress.com/2013/08/26/teaching-naked-part-1/">Teaching Naked, Part 1</a></dt>
<dd>quoth <a href="https://twitter.com/jenebbeler">@jenebbeler</a>: "Incredibly thoughtful post about how a young female prof handled an inappropriate student comment"</dd>
<dt><a href="http://tenureshewrote.wordpress.com/2013/08/29/teaching-naked-part-2/">Teaching Naked, Part 2</a></dt>
<dd>Followup to the first post, on how the administration responded to how she handled the sexual harassment.</dd>
</dl><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=87657" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:87445Dieting FTW2013-10-16T00:48:11Z2013-10-16T00:48:11Zpublic1<p>It's been a few months since <a href="http://winterkoninkje.dreamwidth.org/85582.html">my last dieting update</a>, and things've been going great.</p>
<dl>
<dt>Weight</dt>
<dd>In the first month I lost 13 pounds, but over the second month I didn't lose any. Apparently this sort of plateauing happens; so I've tweaked things a bit, hoping to get back on track. Last week I finally got a scale, so I can keep track of things more often than once a month. And if it's to be believed, I've lost an additional 5 pounds over the last couple weeks.</dd>
<dt>Cholesterol</dt>
<dd>Had another round of bloodwork done a fortnight ago. My cholesterol numbers are down by 90 points. I didn't get a copy of the results, so I can't remember which of the numbers that is exactly; but either way, it's a huge step from extremely high to borderline high.</dd>
<dt>Blood Sugar</dt>
<dd>My FDA is down from 6.2 (borderline pre-diabetic) to 5.3 (normal), which is awesome. Don't recall what the fasting random numbers were, but those are less reliable anyways.</dd>
</dl>
<p>And here's the graphic for my macronutrients over the last four weeks and the last three months. Looks like I've been averaging around 5::6, protein to carbs; which ain't bad, but it'd be nice if I can figure out a way to get it closer to 6::5 or 3::2.</p>
<center><img src="http://llama.freegeek.org/~wren/resources/blog/2013-10-13-nutrients" width="500" height="242" /></center>
<center><img src="http://llama.freegeek.org/~wren/resources/blog/2013-10-13-nutrients-3month.png" width="500" height="242" /></center><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=87445" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:87291Modal logic (columbicubiculomania, pt.V)2013-10-03T23:06:32Z2013-12-08T05:05:13Zpublic0<p>It's been a while since I've posted under this tag, but I made a <a href="http://cl.indiana.edu/~wren/resources/cartography-of-math/ModalLogic.pdf">map of common normal modal logics</a> based off the diagram in <a href="http://plato.stanford.edu/entries/logic-modal/">SEP</a>. I don't have much to say about it, but I'm taking a course on the topic now so hopefully I'll have a bit more to say in the future.</p>
<p>While I was at it, I revised the <a href="http://cl.indiana.edu/~wren/resources/cartography-of-math/BinaryRelations.pdf">map for binary relations</a> (first published <a href="http://winterkoninkje.dreamwidth.org/79427.html">back here</a>). Not too much has changed overall. I added the definition of "dense" (op-transitive) and "shift-reflexive" relations, since these show up in modal logics and so could be interesting elsewhere. I also tightened up the list of entailments to more explicitly capture the difference between the weak and strong definitions of (anti)symmetry. In the new versions, the entailments all hold in minimal logic assuming the substitution principle for equality (if <code>x=y</code> and <code>P(x)</code> then <code>P(y)</code>, for any elements <code>x</code> and <code>y</code> and any property <code>P</code>)— except for those marked with a subscript <code>I</code>, which require intuitionistic logic. In addition, any of the entailments with strong (anti)symmetry as a premise can be strengthened to only require weak (anti)symmetry if we have decidable equality or are working in classical logic.</p>
<p><i>Edit 2013.10.12:</i> Updated these two again. For the relations, just added a note that shift-reflexivity entails density. For the modal logics, added a bunch of new goodies and cleaned things up a bit.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=87291" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:86908wtf.2013-10-01T19:36:15Z2013-10-01T19:36:15Zpublic0<p>So, I just found out that an old friend of mine:
<ul>
<li><a href="http://www.mcso.us/PAID/Home/Booking/1276456">was arrested for domestic violence</a></li>
<li><a href="http://www.scribd.com/doc/170684165/Michael-Schwern-Exonerated">was exonerated</a> (i.e., was not charged)</li>
<li>and <a href="http://geekfeminism.org/2013/09/30/co-signing-the-ada-initiatives-statement-on-michael-schwern/">is now the target of a witchhunt</a>.</li>
</ul></p>
<p>I'm totally torn up about this; both about whatever happened, and about the ongoing reaction. Meanwhile, I can't help but recall the all too timely post of a different friend of mine about <a href="http://www.overseas-exile.com/2013/09/innocent-until-proven-guilty-us-versus.html">what it means to say "innocent until proven guilty"</a>.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=86908" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:86282More commutative operators2013-08-03T06:02:14Z2013-08-03T06:02:14Zpublic0<h3>The final API for (<κ)-commutative operators</h3>
<a href="http://winterkoninkje.dreamwidth.org/86236.html">Last time</a> I talked about generalizing the notion of quasi-unordered pairs to the notion of quasi-unordered multisets. The final API from last time was:
<blockquote><code><pre>type Confusion :: * → *
isSingleton :: Confusion a → Maybe a
size :: Confusion a → Cardinal
observe :: Ord r ⇒ (a → r) → Confusion a → [(r, Either (Confusion a) a)]</pre></code></blockquote>
<p>Now, every function of type <code>Confusion a → b</code> is guaranteed to be a (<κ)-commutative operator, where κ is implicitly given by the definition of <code>Confusion</code>. However, we have no way to construct the arguments to those functions! We need to add a function <b><code>confuse :: ∀λ. 0<λ<κ ⇒ Vector a λ → Confusion a</code></b> so that we can construct arguments for our (<κ)-commutative operators. Of course, rather than using bounded quantification and the <code>Vector</code> type, it'd be a lot easier to just define a type which incorporates this quantification directly:
<blockquote><code><pre>data BoundedList (a::*) :: Nat → * where
BLNil :: BoundedList a n
BLCons :: a → BoundedList a n → BoundedList a (1+n)
data NonEmptyBoundedList (a::*) :: Nat → * where
NEBLSingleton :: a → NonEmptyBoundedList a 1
NEBLCons :: a → NonEmptyBoundedList a n → NonEmptyBoundedList a (1+n)</pre></code></blockquote>
Now we have:
<blockquote><code><pre>confuse :: NonEmptyBoundedList a κ → Confusion a
type Commutative a b = Confusion a → b
runCommutative :: Commutative a b → NonEmptyBoundedList a κ → b
runCommutative f xs = f (confuse xs)</pre></code></blockquote></p>
<p>Ideally, we'd like to take this a step further and have a version of <code>runCommutative</code> which returns a variadic function of type <code>a → ... a → b</code> for the appropriate number of arguments. This way we'd be able to call them like regular curried functions rather than needing to call them as uncurried functions. There are a number of ways to do variadic functions in Haskell, but discussing them would take us too far afield. Naturally, implementing them will amount to taking advantage of the 4-tuple for folding over multisets, which was defined last time.</p>
<h3>Handling κ-commutative operators</h3>
<p>Continuing the theme, suppose we really want to handle the case of κ-commutative operators rather than (<κ)-commutative operators. For simplicity, let's restrict ourselves to finite κ, and let's pretend that Haskell has full dependent types. If so, then we can use the following API:
<blockquote><code><pre>type Confusion :: * → Nat → *
extractSingleton :: Confusion a 1 → a
size :: Confusion a n → Nat
size _ = n
data ConfusionList (r, a :: *) :: Nat → * where
CLNil :: ConfusionList r a 0
CLCons :: r → Confusion a n → ConfusionList r a m → ConfusionList r a (n+m)
observe :: Ord r ⇒ (a → r) → Confusion a n → ConfusionList r a n
confuse :: Vector a (1+n) → Confusion a (1+n)
type Commutative a n b = Confusion a n → b
runCommutative :: Commutative a n b → Vector a n → b
runCommutative f xs = f (confuse xs)</pre></code></blockquote></p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=86282" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:86236Commutative by construction2013-08-03T03:38:18Z2013-08-03T06:03:16Zpublic0<p>Recently gelisam posted an article on <a href="http://gelisam.blogspot.ca/2013/07/the-commutative-monad.html">a combinatorial approach to provably commutative binary operators</a>, which has <a href="http://www.reddit.com/r/haskell/comments/1jegxb/the_commutative_monad">a decent discussion</a> on reddit. Here, I'm going to generalize that idea.</p>
<p><i>Edit (2013-08-03T05:06:58Z):</i> Okay, I should be done tweaking things now.</p>
<p><i>Edit (2013-08-03T06:02:40Z):</i> See also <a href="http://winterkoninkje.dreamwidth.org/86282.html">the followup post</a>.</p>
<h3>Preliminary Definitions</h3>
<p>Let <code>A</code> and <code>B</code> be arbitrary types, and let κ be any non-zero cardinal number (we only really care about finite cardinals, or maybe at most aleph-naught). Let the notation <b><code>A^{κ}</code></b> denote a multiset of elements drawn from <code>A</code> with cardinality exactly κ. And let the notation <b><code>A^{<κ}</code></b> denote a non-empty multiset of elements drawn from <code>A</code> with cardinality not greater than κ.</p>
<h3>Commutative operators</h3>
<p>A <b>κ-commutative operator</b> from <code>A</code> to <code>B</code> can be thought of as a function of type <code>A^{κ} → B</code>. For example:
<ul>
<li>The 1-commutative functions are all the functions of type <code>A → B</code>.</li>
<li>The 2-commutative functions are commutative binary functions, thus a subtype of <code>A → A → B</code>.</li>
<li>The 3-commutative functions are ternary functions which return the same result for all permutation orders of their arguments, thus a subtype of <code>A → A → A → B</code>.</li>
</ul></p>
<p>A <b>(<κ)-commutative operator</b> from <code>A</code> to <code>B</code> can be thought of as a function of type <code>A^{<κ} → B</code>, i.e., a polymorphic function of type <code>∀λ. 0<λ<κ ⇒ A^{λ} → B</code>. Thus, the (<κ)-commutative functions can be thought of as a family of λ-commutative functions, for all non-zero λ not greater than κ, satisfying suitable coherence conditions. However, for finite κ, a simpler representation is to think of them in terms of folds over non-empty multisets; that is, as 4-tuples:
<blockquote><code><pre>(C, h:A→C, f:A→C→C, g:C→B)
such that
∀a,a'∈A, c∈C. f a (f a' c) == f a' (f a c)
∀a,a'∈A. f a (h a') == f a' (h a)</pre></code></blockquote></p>
<p>Alternatively, if you are willing to include the case where <code>λ=0</code>, then use 4-tuples:
<blockquote><code><pre>(C, c0:C, f:A→C→C, g:C→B)
such that
∀a,a'∈A, c∈C. f a (f a' c) == f a' (f a c)</pre></code></blockquote></p>
<h3>Quasi-unordering pairs</h3>
<p>Gelisam's solution to the higher-order problem is to generalize unordered pairs to <b>quasi-unordered pairs</b>: which are, either an unordered pair or else some summary information about a pair which can't be unordered. The way we do this is to have an observation function we apply to each argument. If that observation function can distinguish the arguments, then we can pass the arguments to the function in a canonical order such that we do not betray the original order of the inputs. However, if we cannot distinguish the two arguments, then the best we can do is to return the observation we made on both of them— since, if we returned the actual arguments themselves then we'd betray their input order. Rather than hard-coding the choice of <code>Bool</code> as gelisam did, we can <a href="http://www.reddit.com/r/haskell/comments/1jegxb/the_commutative_monad/cbf4nm2">generalize to any totally ordered set of observations</a>:
<blockquote><code><pre>distinguish :: Ord r ⇒ (a → r) → Commutative a (Either r (a,a))
distinguish f = Commutative $ \ x y ↦
let fx = f x
fy = f y
in
case compare fx fy of
LT ↦ Right (x,y)
EQ ↦ Left fx
GT ↦ Right (y,x)</pre></code></blockquote></p>
<h3>Quasi-unordering multisets</h3>
<p>Now, we want to generalize this to multisets with any non-zero cardinality. Note, because the observations <code>r</code> are totally ordered, the observation function induces an almost-linear partial order on the original domain <code>a</code>. Assume we have some suitable <b>abstract implementation of multisets: <code>Confusion a</code></b>, which implements <code>a^{<κ}</code> for some particular κ. Because the observation function induces an order on our original domain, there exists a function:
<blockquote><code><pre>observe_0 :: Ord r ⇒ (a → r) → Confusion a → [Confusion a]
such that
∀ r f xs0. isOrdered (observe_0 f xs0)
where
isOrdered (xs:xss) =
(∀x,x'∈xs. f x == f x')
⋀ case xss of
[] ↦ True
ys:_ ↦
(∀ x∈xs, y∈ys. f x < f y)
⋀ isOrdered xss</pre></code></blockquote>
That is, every element of the result is a multiset of elements which are equivalent under the observation function, and the elements of previous multisets precede the elements of subsequent multisets. That is, we can take the input multiset which is inherently unordered and return a nearly-linear DAG.</p>
<p>As written <code>observe_0</code> doesn't get us that far, since the implementation of multisets is abstract, and all we've done is break one multiset up into a bunch of multisets. Now, assume our multisets support the function <b><code>isSingleton :: Confusion a → Maybe a</code></b> which tells us whether a multiset is a singleton or not, and gives us the element if it is. Using this, we can strengthen our observing function to:
<blockquote><code><pre>observe_1 :: Ord r ⇒ (a → r) → Confusion a → [Either (Confusion a) a]
observe_1 f
= map (\xs ↦ maybe (Left xs) Right (isSingleton xs))
. observe_0 f</pre></code></blockquote></p>
<p>That gets us pretty much what we want. However, in order to gain the full functionality we had in the binary case, we'd like to have some way to eliminate the remaining multisets. Probably the most general way is to define the following function which also returns the shared observation for classes of inputs which are still confused:
<blockquote><code><pre>observe_2 :: Ord r ⇒ (a → r) → Confusion a → [Either (r, Confusion a) a]
-- or, even better
observe_2' :: Ord r ⇒ (a → r) → Confusion a → [(r, Either (Confusion a) a)]</pre></code></blockquote>
We could implement this in terms of <code>observe_0</code>, however, that means we'd be calling the observation function redundantly since <code>observe_0</code> throws away the results. Thus, it's more efficient to just implement this version directly, in lieu of implementing <cocd>observe_0 at all. The overall complexity will be the same and this version is strictly more powerful.</cocd></p>
<p>If we're returning the result of observing those confusion sets, then why bother returning the confusion set too? The reason is that this way we can apply our observing function again in order to further distinguish those confusion sets. Therefore, this version is complete for composition of observation functions whereas the version that discards the confusion set is not.</p>
<p>And, as a final note, we'd also want to ensure that our multisets support the operation <b><code>size :: Confusion a → Cardinal</code></b>; otherwise, we need to return a triple of the multiset, its size, and its observation. The binary case could avoid this detail since there all confusion sets must be of cardinality 2.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=86236" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:85582Dieting update2013-07-23T01:08:49Z2013-07-23T01:08:49Zpublic0<p>It's been three weeks since I <a href="http://winterkoninkje.dreamwidth.org/84727.html">got the bad news</a> about cholesterol and blood-sugar levels. Three weeks since I've started <a href="http://www.webmd.com/heart-disease/news/20090608/high-protein-diet-goes-vegetarian">this crazy diet</a>. So, I figure it's time for an update on how things are going.</p>
<p>First off: I feel amazing! After just one day I felt more energetic than I have in a long time: I had a lot more pep like I'd upgraded to a more-powerful or smoother-running engine, but it felt like the gas tank was on empty. Makes sense, of course. The former feeling has continued, whereas the latter has gone away as I've gotten used to not relying on the quick boost that sugars give. Also, that feeling of getting winded after climbing a steep hill or those slight stomach cramps after a long hike? I haven't had the slightest glimmer of either since starting. Even after I'm done with the dieting per se, this is definitely going to change the way I eat from now on. The difference is just obscene.</p>
<p>One thing I learned, which apparently everyone else already knows, is that it's the protein what makes you feel full. For the first week, I was so full/unhungry that I had to be careful to keep my calories up. For someone of my stature, it's dangerous when you don't feel like eating more than 1000-or-so calories a day. Protein shakes helped a lot here. By the second week it was easier to get enough calories "naturally", and still easier during the third week. However, I'm still averaging 444 below my stated goal of 2247 (which would amount to losing around 2 pounds/week); which is better than the 514 below of the second week, but not so good as the 266 below of the first week. Even though 2247 is the stated goal according to my phone app, this last week I've been aiming more for 2000. Still, now that I've run the numbers, it looks like I should add the shakes back in. Lo-cal is good and all, but I don't want my body to trigger starvation mode. That'd suck.</p>
<center><img src="http://llama.freegeek.org/~wren/resources/blog/2013-07-22-calories.png" width="500" height="218" /></center>
<p>So, I've been doing good on calories (as in the graphic above). However, getting the 1::1 balance between protein and carbs has been a lot harder (as in the graphic below). The upswing in carbs and downswing in fat on the right should be taken with a grain of salt. The graphics include today, but I've only entered my breakfast so far. Still, I have been allowing myself some more carbs the last two days, so I should be sure to keep that in check. I've got a solid breakfast recipe which isn't quite 1::1 but it's close, and a few nights back Licia made an amazing lasagne which was exactly 1::1, so I'll try to post those in a couple-few days.</p>
<center><img src="http://llama.freegeek.org/~wren/resources/blog/2013-07-22-nutrients.png" width="500" height="238" /></center><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=85582" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:85357ANN: data-fin2013-07-22T07:14:06Z2013-07-22T07:14:06Zpublic1<h3>data-fin 0.1.0</h3>
<p>The data-fin package offers the family of totally ordered finite sets,
implemented as newtypes of <code>Integer</code>, etc. Thus, you get all the joys of:</p>
<blockquote><code><pre>data Nat = Zero | Succ !Nat
data Fin :: Nat -> * where
FZero :: (n::Nat) -> Fin (Succ n)
FSucc :: (n::Nat) -> Fin n -> Fun (Succ n)</pre></code></blockquote>
<p>But with the efficiency of native types instead of unary encodings.</p>
<h3> Notes </h3>
<p>I wrote this package for a linear algebra system I've been working on, but
it should also be useful for folks working on Agda, Idris, etc, who want
something more efficient to compile down to in Haskell. The package is
still highly experimental, and I welcome any and all feedback.</p>
<p>Note that we implement type-level numbers using [1] and [2], which works
fairly well, but not as nicely as true dependent types since we can't
express certain typeclass entailments. Once the constraint solver for
type-level natural numbers becomes available, we'll switch over to using
that.</p>
<p>[1] Oleg Kiselyov and Chung-chieh Shan. (2007) <a href="http://okmij.org/ftp/Haskell/types.html#binary-arithm">Lightweight static resources: Sexy types for embedded and systems programming</a>. <i>Proc. Trends in Functional Programming.</i> New York, 2–4 April 2007.</p>
<p>[2] Oleg Kiselyov and Chung-chieh Shan. (2004) <a href="http://okmij.org/ftp/Haskell/types.html#Prepose">Implicit configurations: or, type classes reflect the values of types</a>. <i>Proc. ACM SIGPLAN 2004 workshop on Haskell.</i> Snowbird, Utah, USA, 22 September 2004. pp.33–44.</p>
<h3>Links</h3>
<ul>
<li>Homepage: <a href="http://code.haskell.org/~wren/">http://code.haskell.org/~wren/</a></li>
<li>Hackage: <a href="http://hackage.haskell.org/package/data-fin">http://hackage.haskell.org/package/data-fin</a></li>
<li>Darcs: <a href="http://community.haskell.org/~wren/data-fin">http://community.haskell.org/~wren/data-fin</a></li>
<li>Haddock: <a href="http://community.haskell.org/~wren/data-fin/dist/doc/html/data-fin/">Darcs version</a></li>
</ul><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=85357" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:85045Notions of powers2013-07-20T23:46:39Z2013-07-22T04:50:52Zpublic4<p>Over on Reddit there's a discussion where one commenter admitted:
<blockquote>"the whole <code>(^)</code> vs <code>(^^)</code> vs <code>(**)</code> [distinction in Haskell] confuses me."</blockquote>
It's clear to me, but it's something they don't teach in primary school, and it's something most programming languages fail to distinguish. The main problem, I think, for both primary ed and for other PLs, is that they have an impoverished notion of what "numbers" could be, and this leads to artificially conflating things which should be kept distinct. I wrote a reply over on Reddit, hoping to elucidate the distinction, but I thought I should repeat it in more persistent venue so it can reach a wider audience.</p>
<p>First, let us recall the basic laws of powers:
<blockquote><code><pre>a^0 = e
a^1 = a
(a^x)^y = a^(x*y)
(a^x)*(a^y) = a^(x+y)
(a*b)^x = (a^x)*(b^x)</pre></code></blockquote></p>
<p>There are two very important things to notice here. First off, our underlying algebra (the <code>a</code>s and <code>b</code>s) only needs to have the notion of multiplication, <code>(*)</code>, with identity, <code>e</code>. Second, our powers (the <code>x</code>s and <code>y</code>s) have an entirely different structure; in particular, they form at least a semiring <code>(+,0,*,1)</code>. Moreover, if we're willing to give up some of those laws, then we can weaken these requirements. For example, if we get rid of <code>a^0 = e</code> then we no longer need our underlying algebra to be a monoid, being a semigroup is enough. And actually, we don't even need it to be a semigroup. We don't need full associativity, all we need for this to be consistent is <a href="http://en.wikipedia.org/wiki/Power_associativity">power-associativity</a>.</p>
<p>So we can go weaker and more abstract, but let's stick here for now. Any time we have a monoid, we get a notion of powers for free. This notion is simply iterating our multiplication, and we use the commutative semiring <code>(Natural,+,0,*,1)</code> in order to represent our iteration count. This is the notion of powers that Haskell's <code>(^)</code> operator captures. Unfortunately, since Haskell lacks a standard <code>Natural</code> type (or <code>Semiring</code> class), the type signature for <code>(^)</code> lies and says we could use <code>Integer</code> (or actually, <code>Num</code> which is the closest thing we have to <code>Ring</code>), but the documentation warns that negative powers will throw exceptions.</p>
<p>Moving on to the <code>(^^)</code> operator: suppose our monoid is actually a group, i.e. it has a notion of reciprocals. Now, we need some way to represent those reciprocals; so if we add subtraction to our powers (yielding the commutative ring <code>(Integer,+,-,0,*,1)</code>), we get the law <code>a^(-x) = 1/(a^x)</code>. The important thing here is to recognize that not all monoids form groups. For example, take the monoid of lists with concatenation. We do have a <code>(^)</code> notion of powers, which may be more familiar as the <code>replicate</code> function from the Prelude. But, what is the reciprocal of a string? what is the inverse of concatenation? The <code>replicate</code> function simply truncates things and treats negative powers as if they were zero, which is on par with <code>(^)</code> throwing exceptions. It is because not all monoids are groups that we need a notion of powers for monoids (i.e., <code>(^)</code>) which is different from the notion of powers for groups (i.e., <code>(^^)</code>). And though Haskell fails to do so, we can cleanly capture this difference in the type signatures for these operations.</p>
<p>Further up, we get another notion of powers which Haskell doesn't highlight; namely the notion of powers that arises from the field <code>(Rational,+,-,0,*,/,1)</code>. To get here, we take our group and add to it the ability to take roots. The fractions in powers are now taken to represent the roots, as in the law <code>a^(1/y) = root y a</code>. Again note that there's a vast discrepancy between our underlying algebra which has multiplication, reciprocals, and roots vs our powers which have addition, subtraction, multiplication, and division.</p>
<p>Pulling it back a bit, what if our monoid has a notion of roots, but does not have inverses? Here our powers form a semifield; i.e., a commutative semiring with multiplicative inverses; e.g., the non-negative rationals. This notion is rather obscure, so I don't fault Haskell for lacking it, though it's worth mentioning.</p>
<p>Finally, <code>(**)</code> is another beast altogether. In all the previous examples of powers there is a strong distinction between the underlying algebra and the powers over that algebra. But here, we get exponentiation; that is, our algebra has an <i>internal</i> notion of powers over <i>itself!</i> This is remarkably powerful and should not be confused with the basic notion of powers. Again, this is easiest to see by looking at where it fails. Consider multiplication of (square) matrices over some semiring. This multiplication is associative, so we can trivially implement <code>(^)</code>. Assuming our semiring is actually a commutative ring then almost all (though not all) matrices have inverses, so we can pretend to implement <code>(^^)</code>. For some elements we can even go so far as <a href="http://en.wikipedia.org/wiki/Square_root_of_a_matrix">taking roots</a>, though we run into the problem of there being multiple roots. But as for exponentiation? It's not even clear that <code>(**)</code> should be meaningful on matrices. Or rather, to the extent that it is meaningful, it's not clear that the result should be a matrix.</p>
<p>N.B., I refer to <code>(**)</code> as exponentials in contrast to <code>(^)</code>, <code>(^^)</code>, etc as powers, following the standard distinction in category theory and elsewhere. Do note, however, that this notion of exponentials is different again from the notion of the antilog <code>exp</code>, i.e. the inverse of <code>log</code>. The log and antilog are maps between additive monoids and multiplicative monoids, with all the higher structure arising from that. We can, in fact, give a notion of <a href="http://en.wikipedia.org/wiki/Matrix_exponential">antilog for matrices</a> if we assume enough about the elements of those matrices.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=85045" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:84971In search of algebraic theories2013-07-15T03:28:20Z2013-07-15T03:28:20Zpublic0<p>An important notion that shows up in algebra is the idea of a free object. For example, we have the following free objects for their corresponding algebraic theories:</p>
<ul>
<li><code>NonemptyList A</code> — free semigroups</li>
<li><code>List A</code> — free monoids</li>
<li><code>NonemptyBag A</code> — free commutative semigroups</li>
<li><code>Bag A</code> [1] — free commutative monoids</li>
<li><code>NonemptySet A</code> — free commutative bands (band = idempotent semigroup)</li>
<li><code>Set A</code> — free commutative bands with identity</li>
</ul>
<p>Recently I've been coming across things whose quotient structure looks like:</p>
<blockquote><code><pre>Foo A B = List (NonemptyMap A (NonemptyList B))
Bar A B = (Foo A B, NonemptyList (A,B))</pre></code></blockquote>
<p>I'm curious if anyone has encountered either of these as free objects of some algebraic theory?</p>
<p>[1] I.e., a multiset. In order to get the proper quotienting structure, we can implement <code>Bag A</code> by <code>Map A Nat</code> where <code>a `elem` xs = member a xs</code> and <code>multiplicity a xs = maybe 0 (1+) (lookup a xs)</code>.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=84971" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:84727Bitties2013-07-03T03:57:07Z2013-07-03T03:57:07Zpublic3<p>Just got back from <a href="http://www.cs.cornell.edu/Conferences/MFPS29/">MFPS</a>-<a href="http://lii.rwth-aachen.de/lics/lics13/">LICS</a>-<a href="http://csf2013.seas.harvard.edu/index.html">CSF</a> saturday night. T'was the first LICS I've been to, and my first time in the deep south. I had fun overall. Definitely enjoyed the French Quarter with its narrower streets, delightful architecture, and other non-American features. And I ran into the Pride parade the day after arriving; I seem to have a knack for that ;) The humidity was killer though.</p>
<p>The slides from my <a href="http://www.indiana.edu/~iulg/nlcs.html">NLCS</a> talk are <a href="http://llama.freegeek.org/~wren/pubs/chiastic_nlcs2013.pdf">available here</a>. I've been having some issues with my bibtex2html script, so they're not linked to on the publications page yet; but they will be once I get that issue fixed.</p>
<p>In less happy news, I got some bloodwork back today. Cholesterol is far far too high, and I'm getting into the pre-diabetic range for bloodsugar levels. So, I'm starting a major diet change in hopes of getting those under control. Apparently lack of protein is a big part of the problem (for me), which is ironic since most americans get far too much. Damn midwestern genes. Went grocery shopping today; it's profoundly difficult to get a 1::1 carbs-to-protein ratio as a vegetarian.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=84727" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:84469Dungeon World: Assassin class2013-06-06T22:34:58Z2013-06-09T00:32:03Zpublic0<p>After far too long, I've finally found a new roleplaying group. We're using <a href="http://www.dungeon-world.com/">Dungeon World</a>, a lightweight system I've never used before. It's a class-based system, which I've never been too fond of, but it does seem like it gets rid of most of the things I hate about class-based systems. The core book only gives the standard D&D-style classes, but they give some guidelines on making up your own classes. For my character I worked with the GM to come up with a new <a href="http://llama.freegeek.org/~wren/resources/blog/assassin.pdf">Assassin</a> class which combines some of the traits of the Thief and the Fighter. I tried to make sure it's balanced against the other classes and doesn't obviate the Thief/Fighter, but not having used DW before it's hard to be sure. If you've used DW and have any comments, I'd be interested in hearing them.</p>
<p><i>Edit:</i> I've posted a new version which adjusts the damage option for the Death Dealer and Assassin's Strike moves. Also included is a discussion about how different ways of doing DD/AS would affect DPS, which is necessary for doing a fair comparison against other classes. If you run a game with this class, let me know how it goes.</p><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=84469" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> commentstag:dreamwidth.org,2010-05-25:518115:83994ANN: prelude-safeenum2013-05-30T00:05:57Z2013-05-30T00:05:57Zpublic0<h3>prelude-safeenum 0.1.0</h3>
<p>The prelude-safeenum package offers a safe alternative to the Prelude's <code>Enum</code> class in order to render it safe. While we're at it, we also generalize the notion of enumeration to support types which can only be enumerated in one direction.</p>
<h3>Description</h3>
<p>The prelude-safeenum package offers an alternative to the notion of enumeration provided by the Prelude. For now it is just a package, but the eventual goal is to be incorporated into haskell prime. Some salient characteristics of the new type-class hierarchy are:</p>
<dl>
<dt>Removes partial functions</dt>
<dd>The Haskell Language Report <a href="http://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1310006.3.4">section 6.3.4</a> defines <code>pred</code>, <code>succ</code>, <code>fromEnum</code>, and <code>toEnum</code> to be partial functions when the type is <code>Bounded</code>, but this is unacceptable. The new classes remove this problem by correcting the type signatures for these functions.</dd>
<dt>Generalizes the notion of enumeration</dt>
<dd>Rather than requiring that the type is linearly enumerable, we distinguish between forward enumeration (which allows for multiple predecessors) and backward enumeration (which allows for multiple successors).</dd>
<dt>Adds new functions: <code>enumDownFrom</code>, <code>enumDownFromTo</code></dt>
<dd>One of the big problems with the partiality of <code>pred</code> is that there is no safe way to enumerate downwards since in the border case <code>enumFromThen x (pred x)</code> will throw an error rather than evaluating to <code>[x]</code> as desired. These new functions remove this problem.</dd>
<dt>Removes the requirement...</dt>
<dd>...that the enumeration order coincides with the
<code>Ord</code> ordering (if one exists). Though, of course, it's advisable to keep
them in sync if possible, for your sanity.</dd>
<dt>Ensures that the notion of enumeration is well-defined</dt>
<dd>This much-needed rigor clarifies the meaning of enumeration. In addition, it rules out instances for <code>Float</code> and <code>Double</code> which are highly problematic and often confuse newcomers to Haskell. Unfortunately, this rigor does render the instance for <code>Ratio</code> problematic. However, <code>Ratio</code> instances <i>can</i> be provided so long as the base type is enumerable (and <code>Integral</code>, naturally); but they must be done in an obscure order that does not coincide with <code>Ord</code>.
<dt>The obscure order required for well-defined enumeration of <code>Ratio</code> is provided.</dt>
</dd></dl>
<h3>Links</h3>
<ul>
<li>Homepage: <a href="http://code.haskell.org/~wren/">http://code.haskell.org/~wren/</a></li>
<li>Hackage: <a href="http://hackage.haskell.org/package/prelude-safeenum">http://hackage.haskell.org/package/prelude-safeenum</a></li>
<li>Darcs: <a href="http://community.haskell.org/~wren/prelude-safeenum">http://community.haskell.org/~wren/prelude-safeenum</a></li>
<li>Haddock: <a href="http://community.haskell.org/~wren/prelude-safeenum/dist/doc/html/prelude-safeenum/">Darcs version</a></li>
</ul><br /><br /><img src="http://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&ditemid=83994" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/> comments