Prefix Operators in Haskell
However, there is still reason to celebrate: many Haskell operators do support prefix notation! This was a mind-blower to me, since I hadn't heard about this until last night...
At the Data Day Texas conference this past Saturday, O'Reilly/StrataConf had a fantastic booth. Among the many cool give-aways they were doing, I obtained a coupon for a free ebook and another for 50% off. Upon returning home and having made my free book decision, I was vacillating between an OCaml book and the famous Haskell one. I've done a little Haskell in the past but have never touched OCaml, so I was pretty tempted.
However, something amazing happened next. I stumbled upon a page that was comparing OCaml and Haskell, which led to another page... where Haskell prefix notation was mentioned. I know many Haskellers who might read this would shrug, or say "yeah, we know", but this was quite a delightful little discovery for me :-)
I don't remember the first page I found, but since then, I've come across a couple more resources:
As such, I needed to do a lot more exploration. Initially, I was really excited and thought I'd be able to convert all Haskell forms to s-expressions (imports, lets, etc.), but I quickly found this was not the case. But the stuff that did work is pretty cool, and I saved it in a series of gists for your viewing pleasure :-)
The first test was pretty simple. Finding success, I thought I'd try something I do when using a Lisp/Scheme interpreter as a calculator. As you can see below, that didn't work (the full traceback is elided). Searching on Hoogλe got me to the answer I was looking for, though. Off to a good start:
I checked some basic operators next, and a function. Everything's good so far:
Here are some basic list operations, including the ever-so-cool list difference operator, (\\). Also, I enjoyed the cons (:) so much that I made a t-shirt of it :-) (See the postscript below for more info.)
I'm not sure if one can do any more prefixing than this for list comprehensions:
Same thing for functions; nothing really exciting to see. (Btw, these examples were lifted from LYHGG.)
Things get a little more interesting with lambda expressions, especially when a closure is added for spice:
Using the compose operator in prefix notation is rather... bizarre :-) It looks much more natural as a series of compositions in a lambda. I also added a mostly-standard view of the compose operator for comparison:
I've saved the best for last, an example of the sort of thing I need when doing matrix operations in game code, graphics, etc. The first one is standard Haskell...
Wow. Such abstract. So brains.
Note that to make the prefix version anywhere close to legible, I added whitepsace. (If you paste this in ghci, you'll see a bunch of prompts, and then the result. If you're running in the Sublime REPL, be sure to scroll to the right.)
And that pretty much wraps up what I did on Sunday afternoon :-)
- Travis Hartwell, Twisted hacker from back in the day, let me know about a great Haskell tutorial for Lispers.
- Here's a fun Lisper-oriented monad tutorial. Also, here's the best monad tutorial I've ever read.
- Liskell (ILC 2007 presentation; paper; 2009 update; source code)
- Lisk (Chris' lisk github repo seems to have disappeared, with the possible exception of an old fork)
- Husk Scheme (main page; github; Hackage)
If you're in the San Antonio / Austin area (or SF; I'll be there in March) and want to go in on a t-shirt order, let me know :-) We need at least six for the smallest order (tri-blend Next Level; these are a bit pricey, but they feel GREAT). I'll collect payment before I make an order.