|
|
On 06/09/2011 11:23 AM, Invisible wrote:
> Anyway, just for giggles, I wanted to see if I could hack the language
> hard enough to make it support separators. The answer is... yeah, kinda.
>
> insert|< 5 # my_heap >|j
I managed to go one better:
insert&(5, my_heap)
Works for any valid Haskell function. With one small catch:
foo&() -- Works fine.
foo&(1) -- Doesn't work at all.
foo&(1, 2) -- Works fine.
foo&(1, 2, 3) -- Works fine.
...
Basically, the syntax "(1, 2, 3)" defines what Haskell calls a "tuple".
You can write functions that accept a tuple:
add (x, y, z) = x + y + z
You then then write "add (1, 2, 3)", but due to Haskell's parsing rules,
"add(1, 2, 3)" (without the space) is also valid. And looks exactly like
a function call in any other language.
Trouble is, it works only if the function you call is /expecting/ a
tuple. As far as Haskell is concerned, "add" is a 1-argument function,
not a 3-argument function.
With some clever type hackery, you can make a "&" operator (or any other
operator name you'd like, providing it isn't reserved) that "un-tuples"
a tuple. Using this, you can supply tuples to any existing Haskell function.
There's a glitch, however: Haskell is tuple sizes from 2 upwards. (IIRC,
the language spec guarantees that sizes up to 5 will exist.) Haskell
also has a size-zero tuple, commonly used as a dummy value for when you
don't actually need to put data somewhere. But it doesn't have a size-1
tuple. Because, let's face it, what would be the point of that?
As a result of this, foo&(5) is actually foo&5. And I can't get it so
that that works. I can make it so a different sort of bracket works, or
a different operator works, but I can't make it consistent with the rest.
And so ends today's lesson in raping your language syntax. :-)
{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances #-}
module Test where
class Tuple t r where
type Function t r :: *
(&) :: Function t r -> t -> r
instance Tuple () r where
type Function () r = r
f & () = f
instance Tuple (x,y) r where
type Function (x,y) r = x -> y -> r
f & (x,y) = f x y
instance Tuple (x,y,z) r where
type Function (x,y,z) r = x -> y -> z -> r
f & (x,y,z) = f x y z
instance Tuple (x,y,z,w) r where
type Function (x,y,z,w) r = x -> y -> z -> w -> r
f & (x,y,z,w) = f x y z w
Post a reply to this message
|
|