POV-Ray : Newsgroups : povray.off-topic : My hypothesis : Re: My hypothesis Server Time
29 Jul 2024 20:15:55 EDT (-0400)
  Re: My hypothesis  
From: Invisible
Date: 6 Sep 2011 06:49:01
Message: <4e65fa9d@news.povray.org>
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

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.